katello 4.4.0.rc1 → 4.4.0.rc2

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 (139) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +10 -1
  3. data/app/controllers/katello/api/v2/repositories_controller.rb +3 -0
  4. data/app/lib/actions/katello/repository/errata_mail.rb +4 -5
  5. data/app/lib/actions/katello/repository/sync.rb +2 -2
  6. data/app/lib/actions/pulp3/abstract.rb +1 -1
  7. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +14 -4
  8. data/app/lib/actions/pulp3/content_view_version/create_import_history.rb +1 -2
  9. data/app/lib/actions/pulp3/repository/reclaim_space.rb +3 -10
  10. data/app/lib/katello/util/pulpcore_content_filters.rb +2 -1
  11. data/app/models/katello/candlepin/repository_mapper.rb +1 -0
  12. data/app/models/katello/concerns/audit_comment_extensions.rb +17 -0
  13. data/app/models/katello/concerns/host_managed_extensions.rb +11 -1
  14. data/app/models/katello/concerns/smart_proxy_extensions.rb +1 -0
  15. data/app/models/katello/content_view_version_export_history.rb +2 -1
  16. data/app/models/katello/content_view_version_import_history.rb +4 -4
  17. data/app/models/katello/host_available_module_stream.rb +10 -0
  18. data/app/models/katello/installed_package.rb +1 -0
  19. data/app/models/katello/root_repository.rb +14 -2
  20. data/app/models/setting/content.rb +9 -2
  21. data/app/services/katello/pulp3/api/yum.rb +4 -0
  22. data/app/services/katello/pulp3/repository/yum.rb +11 -4
  23. data/app/services/katello/pulp3/repository.rb +4 -2
  24. data/app/views/foreman/job_templates/remove_packages_by_search_query.erb +19 -0
  25. data/app/views/foreman/job_templates/update_packages_by_search_query.erb +19 -0
  26. data/app/views/katello/api/v2/content_views/base.json.rabl +8 -4
  27. data/app/views/katello/api/v2/host_module_streams/base.json.rabl +1 -0
  28. data/db/migrate/20210119162528_delete_puppet_and_ostree_repos.rb +2 -0
  29. data/db/migrate/20211019192121_create_cdn_configuration.katello.rb +11 -2
  30. data/db/migrate/20220209205137_expand_sync_timeout_settings.rb +23 -0
  31. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/apply-errata.controller.js +10 -3
  32. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +4 -0
  33. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +17 -12
  34. data/lib/katello/plugin.rb +2 -0
  35. data/lib/katello/repository_types/ostree.rb +0 -6
  36. data/lib/katello/version.rb +1 -1
  37. data/webpack/components/Errata/index.js +57 -57
  38. data/webpack/components/ErratumTypeLabel.js +16 -16
  39. data/webpack/components/MultiSelect/index.js +2 -2
  40. data/webpack/components/Select/Select.js +1 -1
  41. data/webpack/components/SelectOrg/SelectOrgReducer.js +15 -15
  42. data/webpack/components/SelectOrg/SetOrganization.js +1 -1
  43. data/webpack/components/Table/TableHooks.js +1 -0
  44. data/webpack/components/Table/TableWrapper.js +4 -1
  45. data/webpack/components/TypeAhead/helpers/commonPropTypes.js +1 -1
  46. data/webpack/components/TypeAhead/helpers/helpers.js +14 -14
  47. data/webpack/components/TypeAhead/pf3Search/TypeAheadSearch.js +1 -1
  48. data/webpack/components/WithOrganization/withOrganization.js +3 -3
  49. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesActions.js +32 -1
  50. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesConstants.js +3 -2
  51. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js +5 -3
  52. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +1 -0
  53. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErratumExpansionContents.js +3 -3
  54. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsActions.js +16 -0
  55. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsConstants.js +3 -0
  56. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsSelectors.js +19 -0
  57. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +241 -0
  58. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/__tests__/moduleStreamsTab.test.js +108 -0
  59. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/__tests__/modules.fixtures.json +34 -0
  60. data/webpack/components/extensions/HostDetails/Tabs/PackageInstallModal.js +5 -5
  61. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab.js +255 -79
  62. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +76 -0
  63. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +4 -0
  64. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +259 -9
  65. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +22 -26
  66. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +13 -0
  67. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +4 -0
  68. data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +1 -1
  69. data/webpack/components/extensions/RegistrationCommands/fields/LifecycleEnvironment.js +1 -1
  70. data/webpack/components/extensions/about/SystemStatuses.js +1 -1
  71. data/webpack/components/extensions/about/SystemStatusesReducer.js +10 -10
  72. data/webpack/components/pf3Table/components/Table.js +2 -2
  73. data/webpack/components/pf3Table/components/TableBody.js +2 -2
  74. data/webpack/redux/OrganizationProducts/OrganizationProductsReducer.js +15 -15
  75. data/webpack/redux/reducers/RedHatRepositories/enabled.js +43 -43
  76. data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.js +43 -43
  77. data/webpack/redux/reducers/RedHatRepositories/sets.js +31 -31
  78. data/webpack/scenes/AnsibleCollections/AnsibleCollectionsReducer.js +26 -26
  79. data/webpack/scenes/AnsibleCollections/Details/AnsibleCollectionDetailsReducer.js +19 -19
  80. data/webpack/scenes/Content/Table/ContentTable.js +1 -1
  81. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +2 -1
  82. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignHostsForm.js +2 -2
  83. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +1 -1
  84. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +1 -1
  85. data/webpack/scenes/ContentViews/Details/ContentViewDetailReducer.js +8 -8
  86. data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositoryTable.js +1 -1
  87. data/webpack/scenes/ContentViews/Details/Filters/ArtifactsWithNoErrata.js +8 -8
  88. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +1 -1
  89. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +1 -1
  90. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +1 -1
  91. data/webpack/scenes/ContentViews/Details/Filters/CVFilterDetailType.js +46 -46
  92. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +14 -14
  93. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +14 -14
  94. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +1 -1
  95. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +1 -1
  96. data/webpack/scenes/ContentViews/Details/Filters/Rules/Package/AddEditPackageRuleModal.js +17 -17
  97. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +1 -1
  98. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionContent.js +19 -18
  99. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVEnvironmentSelectionForm.js +18 -18
  100. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js +3 -3
  101. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignHostsForm.js +3 -3
  102. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +1 -1
  103. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +1 -1
  104. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +1 -1
  105. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +46 -34
  106. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionRepositoryCell.js +65 -48
  107. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.test.js +1 -1
  108. data/webpack/scenes/ContentViews/Publish/CVPublishFinish.js +2 -2
  109. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +4 -4
  110. data/webpack/scenes/ContentViews/components/EnvironmentLabels.js +18 -18
  111. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +10 -10
  112. data/webpack/scenes/ContentViews/expansions/DetailsExpansion.js +2 -2
  113. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +7 -7
  114. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceTemplate.js +7 -7
  115. data/webpack/scenes/Hosts/ChangeContentSource/components/FormField.js +3 -3
  116. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetailsReducer.js +18 -18
  117. data/webpack/scenes/ModuleStreams/ModuleStreamsReducer.js +26 -26
  118. data/webpack/scenes/Organizations/OrganizationReducer.js +8 -8
  119. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepositoryContent.js +4 -4
  120. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepositories.js +1 -1
  121. data/webpack/scenes/Settings/SettingsReducer.js +14 -14
  122. data/webpack/scenes/Settings/Tables/TableReducer.js +23 -23
  123. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailInfo.js +2 -2
  124. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProductContent.js +15 -15
  125. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProducts.js +1 -1
  126. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailReducer.js +34 -34
  127. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +13 -13
  128. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/AirGappedTypeForm.js +3 -3
  129. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +4 -4
  130. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/UpstreamServerTypeForm.js +3 -3
  131. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +5 -5
  132. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +16 -16
  133. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +149 -149
  134. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsReducer.js +41 -41
  135. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Dialogs/DeleteDialog.js +6 -6
  136. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Table.js +12 -12
  137. data/webpack/services/index.js +36 -36
  138. data/webpack/utils/helpers.js +5 -5
  139. metadata +16 -6
@@ -74,19 +74,19 @@ const CVPackageGroupFilterContent = ({
74
74
  const fetchItems = useCallback((params) => {
75
75
  const adjustedParams = { ...params };
76
76
  switch (selectedIndex) {
77
- case 0:
78
- adjustedParams.show_all_for = 'content_view_filter';
79
- adjustedParams.available_for = undefined;
80
- break;
81
- case 1:
82
- adjustedParams.show_all_for = undefined;
83
- adjustedParams.available_for = undefined;
84
- break;
85
- case 2:
86
- adjustedParams.show_all_for = undefined;
87
- adjustedParams.available_for = 'content_view_filter';
88
- break;
89
- default:
77
+ case 0:
78
+ adjustedParams.show_all_for = 'content_view_filter';
79
+ adjustedParams.available_for = undefined;
80
+ break;
81
+ case 1:
82
+ adjustedParams.show_all_for = undefined;
83
+ adjustedParams.available_for = undefined;
84
+ break;
85
+ case 2:
86
+ adjustedParams.show_all_for = undefined;
87
+ adjustedParams.available_for = 'content_view_filter';
88
+ break;
89
+ default:
90
90
  }
91
91
 
92
92
  return getCVFilterPackageGroups(cvId, filterId, adjustedParams);
@@ -234,7 +234,7 @@ const CVPackageGroupFilterContent = ({
234
234
  </Select>
235
235
  </SplitItem>
236
236
  <SplitItem>
237
- <Button isDisabled={!hasNotAddedSelected} onClick={bulkAdd} variant="secondary" aria-label="add_filter_rule">
237
+ <Button isDisabled={!hasNotAddedSelected} onClick={bulkAdd} variant="primary" aria-label="add_filter_rule">
238
238
  {__('Add filter rule')}
239
239
  </Button>
240
240
  </SplitItem>
@@ -179,7 +179,7 @@ const CVRpmFilterContent = ({
179
179
  {hasPermission(permissions, 'edit_content_views') &&
180
180
  <Split hasGutter>
181
181
  <SplitItem>
182
- <Button onClick={() => setModalOpen(true)} variant="secondary" aria-label="add_rpm_rule">
182
+ <Button onClick={() => setModalOpen(true)} variant="primary" aria-label="add_rpm_rule">
183
183
  {__('Add RPM rule')}
184
184
  </Button>
185
185
  </SplitItem>
@@ -136,7 +136,7 @@ const ContentViewFilters = ({ cvId, details }) => {
136
136
  <>
137
137
  <Split hasGutter>
138
138
  <SplitItem>
139
- <Button onClick={openAddModal} variant="secondary" aria-label="create_filter">
139
+ <Button onClick={openAddModal} variant="primary" aria-label="create_filter">
140
140
  {__('Create filter')}
141
141
  </Button>
142
142
  </SplitItem>
@@ -36,11 +36,11 @@ const AddEditPackageRuleModal = ({ filterId, onClose, selectedFilterRuleData })
36
36
 
37
37
  const versionText = () => {
38
38
  switch (true) {
39
- case !!editingVersion: return VersionModifiers['Equal to'];
40
- case !!editingMinVersion && !editingMaxVersion: return VersionModifiers['Greater than'];
41
- case !editingMinVersion && !!editingMaxVersion: return VersionModifiers['Less than'];
42
- case !!editingMinVersion && !!editingMaxVersion: return VersionModifiers.Range;
43
- default: return VersionModifiers['All versions'];
39
+ case !!editingVersion: return VersionModifiers['Equal to'];
40
+ case !!editingMinVersion && !editingMaxVersion: return VersionModifiers['Greater than'];
41
+ case !editingMinVersion && !!editingMaxVersion: return VersionModifiers['Less than'];
42
+ case !!editingMinVersion && !!editingMaxVersion: return VersionModifiers.Range;
43
+ default: return VersionModifiers['All versions'];
44
44
  }
45
45
  };
46
46
 
@@ -64,18 +64,18 @@ const AddEditPackageRuleModal = ({ filterId, onClose, selectedFilterRuleData })
64
64
 
65
65
  const formVersionParams = () => {
66
66
  switch (versionComparator) {
67
- case 'All versions':
68
- return {};
69
- case 'Equal to':
70
- return { version };
71
- case 'Greater than':
72
- return { min_version: minVersion };
73
- case 'Less than':
74
- return { max_version: maxVersion };
75
- case 'Range':
76
- return { min_version: minVersion, max_version: maxVersion };
77
- default:
78
- return {};
67
+ case 'All versions':
68
+ return {};
69
+ case 'Equal to':
70
+ return { version };
71
+ case 'Greater than':
72
+ return { min_version: minVersion };
73
+ case 'Less than':
74
+ return { max_version: maxVersion };
75
+ case 'Range':
76
+ return { min_version: minVersion, max_version: maxVersion };
77
+ default:
78
+ return {};
79
79
  }
80
80
  };
81
81
 
@@ -284,7 +284,7 @@ const ContentViewRepositories = ({ cvId, details }) => {
284
284
  <SplitItem>
285
285
  <ActionList>
286
286
  <ActionListItem>
287
- <Button onClick={addBulk} isDisabled={!hasNotAddedSelected} variant="secondary" aria-label="add_repositories">
287
+ <Button onClick={addBulk} isDisabled={!hasNotAddedSelected} variant="primary" aria-label="add_repositories">
288
288
  {__('Add repositories')}
289
289
  </Button>
290
290
  </ActionListItem>
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { camelCase } from 'lodash';
4
- import { Link } from 'react-router-dom';
5
2
  import { translate as __ } from 'foremanReact/common/I18n';
6
3
  import { urlBuilder } from 'foremanReact/common/urlHelpers';
7
- import ContentConfig from './../../../Content/ContentConfig';
4
+ import { camelCase } from 'lodash';
5
+ import PropTypes from 'prop-types';
6
+ import { Link } from 'react-router-dom';
7
+ import ContentConfig from '../../../Content/ContentConfig';
8
8
  import InactiveText from '../../components/InactiveText';
9
9
 
10
10
  const ContentViewVersionContent = ({ cvId, versionId, cvVersion }) => {
@@ -19,19 +19,20 @@ const ContentViewVersionContent = ({ cvId, versionId, cvVersion }) => {
19
19
 
20
20
 
21
21
  const contentConfigTypes = ContentConfig.filter(({ names: { singularLabel } }) =>
22
- !!cvVersion[`${singularLabel}_count`]).map(({
23
- names: {
24
- singularLabel, singularLowercase, pluralLowercase, pluralLabel,
25
- },
26
- }) => {
27
- const countParam = `${singularLabel}_count`;
28
- const count = cvVersion[countParam];
29
- return {
30
- pluralLabel,
31
- label: count > 1 ? pluralLowercase : singularLowercase,
32
- count,
33
- };
34
- });
22
+ !!cvVersion[`${singularLabel}_count`])
23
+ .map(({
24
+ names: {
25
+ singularLabel, singularLowercase, pluralLowercase, pluralLabel,
26
+ },
27
+ }) => {
28
+ const countParam = `${singularLabel}_count`;
29
+ const count = cvVersion[countParam];
30
+ return {
31
+ pluralLabel,
32
+ label: count > 1 ? pluralLowercase : singularLowercase,
33
+ count,
34
+ };
35
+ });
35
36
 
36
37
  const noCounts =
37
38
  !Number(debCount) && !Number(dockerManifestCount) && !Number(dockerTagCount) &&
@@ -61,7 +62,7 @@ const ContentViewVersionContent = ({ cvId, versionId, cvVersion }) => {
61
62
  {dockerManifestCount > 0 && dockerTagCount > 0 &&
62
63
  <>
63
64
  <Link to={`/versions/${versionId}/dockerTags`}>
64
- {`${dockerTagCount} Docker tags`}
65
+ {`${dockerTagCount} Container tags`}
65
66
  </Link><br />
66
67
  <a href={urlBuilder(`content_views/${cvId}#/versions/${versionId}/dockerTags`, '')}>{`${dockerManifestCount} Container manifests`}</a><br />
67
68
  </>
@@ -96,24 +96,24 @@ const CVEnvironmentSelectionForm = () => {
96
96
  id, name, activation_key_count: akCount,
97
97
  host_count: hostCount,
98
98
  }, rowIndex) =>
99
- (
100
- <Tr key={`${name}_${id}`}>
101
- <Td
102
- key={`${name}__${id}_select`}
103
- select={{
104
- rowIndex,
105
- onSelect: (event, isSelected) => onSelect(event, isSelected, id),
106
- isSelected: selectedEnvSet.has(id) || deleteFlow || removeDeletionFlow,
107
- disable: deleteFlow || removeDeletionFlow,
108
- }}
109
- />
110
- <Td>
111
- {name}
112
- </Td>
113
- <Td>{hostCount}</Td>
114
- <Td>{akCount}</Td>
115
- </Tr>
116
- ))
99
+ (
100
+ <Tr key={`${name}_${id}`}>
101
+ <Td
102
+ key={`${name}__${id}_select`}
103
+ select={{
104
+ rowIndex,
105
+ onSelect: (event, isSelected) => onSelect(event, isSelected, id),
106
+ isSelected: selectedEnvSet.has(id) || deleteFlow || removeDeletionFlow,
107
+ disable: deleteFlow || removeDeletionFlow,
108
+ }}
109
+ />
110
+ <Td>
111
+ {name}
112
+ </Td>
113
+ <Td>{hostCount}</Td>
114
+ <Td>{akCount}</Td>
115
+ </Tr>
116
+ ))
117
117
  }
118
118
  </Tbody>
119
119
  </TableComposable>}
@@ -117,9 +117,9 @@ const CVReassignActivationKeysForm = () => {
117
117
  >
118
118
  <AffectedActivationKeys
119
119
  {...{
120
- cvId,
121
- versionEnvironments,
122
- selectedEnvSet,
120
+ cvId,
121
+ versionEnvironments,
122
+ selectedEnvSet,
123
123
  }}
124
124
  deleteCV={false}
125
125
  />
@@ -114,9 +114,9 @@ const CVReassignHostsForm = () => {
114
114
  >
115
115
  <AffectedHosts
116
116
  {...{
117
- cvId,
118
- versionEnvironments,
119
- selectedEnvSet,
117
+ cvId,
118
+ versionEnvironments,
119
+ selectedEnvSet,
120
120
  }}
121
121
  deleteCV={false}
122
122
  />
@@ -71,7 +71,7 @@ const AffectedActivationKeys = ({
71
71
  </Td>
72
72
  <Td><EnvironmentLabels environments={environment} /></Td>
73
73
  </Tr>
74
- ))
74
+ ))
75
75
  }
76
76
  </Tbody>
77
77
  </TableWrapper>
@@ -72,7 +72,7 @@ const AffectedHosts = ({
72
72
  <Td><EnvironmentLabels environments={environment} /></Td>
73
73
  </Tr>
74
74
  ))
75
- }
75
+ }
76
76
  </Tbody>
77
77
  </TableWrapper>
78
78
  );
@@ -284,7 +284,7 @@ export default ({ cvId, versionId }) => [
284
284
  ],
285
285
  },
286
286
  {
287
- name: __('Docker Tags'),
287
+ name: __('Container tags'),
288
288
  route: 'dockerTags',
289
289
  repoType: 'docker',
290
290
  getCountKey: item => item?.docker_tag_count,
@@ -1,21 +1,31 @@
1
1
  /* eslint-disable react/no-array-index-key */
2
- import React, { useState, useEffect } from 'react';
3
- import { head } from 'lodash';
4
- import PropTypes from 'prop-types';
5
- import { useSelector, shallowEqual } from 'react-redux';
6
- import { Grid, Select, SelectOption, SelectVariant } from '@patternfly/react-core';
2
+ import React, { useState } from 'react';
7
3
  import { translate as __ } from 'foremanReact/common/I18n';
8
- import { TableVariant, Thead, Tbody, Tr, Th, Td } from '@patternfly/react-table';
4
+ import PropTypes from 'prop-types';
5
+ import {
6
+ shallowEqual,
7
+ useSelector,
8
+ } from 'react-redux';
9
+ import {
10
+ Grid,
11
+ Select,
12
+ SelectOption,
13
+ SelectVariant,
14
+ } from '@patternfly/react-core';
15
+ import {
16
+ TableVariant,
17
+ Tbody,
18
+ Td,
19
+ Th,
20
+ Thead,
21
+ Tr,
22
+ } from '@patternfly/react-table';
23
+ import { useUrlParams } from '../../../../../components/Table/TableHooks';
9
24
  import TableWrapper from '../../../../../components/Table/TableWrapper';
10
25
  import { TableType } from './ContentViewVersionDetailConfig';
11
26
 
12
- const ContentViewVersionDetailsTable = ({ tableConfig, repositories }) => {
13
- const ALL_REPOSITORIES = __('All Repositories');
14
- const [searchQuery, updateSearchQuery] = useState('');
15
- const [open, setOpen] = useState(false);
16
- const [selected, setSelected] = useState(0);
17
- const [selectedList, setSelectedList] = useState([]);
18
- const {
27
+ const ContentViewVersionDetailsTable = ({
28
+ tableConfig: {
19
29
  name,
20
30
  repoType,
21
31
  responseSelector,
@@ -24,33 +34,35 @@ const ContentViewVersionDetailsTable = ({ tableConfig, repositories }) => {
24
34
  fetchItems,
25
35
  columnHeaders,
26
36
  disableSearch,
27
- } = tableConfig;
37
+ }, repositories,
38
+ }) => {
39
+ const ALL_REPOSITORIES = __('All Repositories');
40
+ const [searchQuery, updateSearchQuery] = useState('');
41
+ const [open, setOpen] = useState(false);
42
+ const { repository_id: urlParamId } = useUrlParams();
43
+
44
+ const relevantRepositories = repositories
45
+ .filter(({ content_type: contentType }) => repoType === contentType);
46
+
47
+ const selectedList = relevantRepositories.length > 1 ? [
48
+ {
49
+ id: undefined,
50
+ name: ALL_REPOSITORIES,
51
+ },
52
+ ...relevantRepositories] :
53
+ relevantRepositories;
54
+
55
+ const presetIndex = selectedList
56
+ .findIndex(({ library_instance_id: id }) =>
57
+ id === Number(urlParamId));
58
+ const [selected, setSelected] = useState(presetIndex ?? 0);
28
59
 
29
60
  const response = useSelector(responseSelector, shallowEqual);
30
61
  const { results, ...metadata } = response;
31
62
  const status = useSelector(statusSelector, shallowEqual);
32
63
 
33
- useEffect(() => {
34
- const relevantRepositories = repositories
35
- .filter(({ content_type: contentType }) => repoType === contentType);
36
-
37
- switch (relevantRepositories.length) {
38
- case 1:
39
- setSelected(head(relevantRepositories));
40
- setSelectedList([...relevantRepositories]);
41
- break;
42
- default:
43
- setSelected(0);
44
- setSelectedList([{
45
- id: undefined,
46
- name: ALL_REPOSITORIES,
47
- }, ...relevantRepositories]);
48
- break;
49
- }
50
- }, [repositories, ALL_REPOSITORIES, repoType]);
51
-
52
64
  const fetchItemsWithRepositoryId = (params) => {
53
- if (selectedList.length === 1) return fetchItems(params);
65
+ if (selectedList?.length === 1) return fetchItems(params);
54
66
  return fetchItems({ repository_id: selectedList[selected]?.id, ...params });
55
67
  };
56
68
 
@@ -1,14 +1,18 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
2
  import { translate as __ } from 'foremanReact/common/I18n';
4
3
  import { urlBuilder } from 'foremanReact/common/urlHelpers';
5
- import { isEmpty } from 'lodash';
4
+ import {
5
+ camelCase,
6
+ isEmpty,
7
+ } from 'lodash';
8
+ import PropTypes from 'prop-types';
9
+ import { Link } from 'react-router-dom';
6
10
  import {
7
11
  Grid,
8
12
  GridItem,
9
13
  } from '@patternfly/react-core';
10
- import InactiveText from '../../../components/InactiveText';
11
14
  import ContentConfig from '../../../../Content/ContentConfig';
15
+ import InactiveText from '../../../components/InactiveText';
12
16
 
13
17
  const ContentViewVersionRepositoryCell = ({
14
18
  data: {
@@ -18,49 +22,45 @@ const ContentViewVersionRepositoryCell = ({
18
22
  },
19
23
  }) => {
20
24
  const CONTENT_COUNTS = {
21
- ansible_collection: {
22
- name: __('Ansible collections'),
23
- url: `ansible_collections?repositoryId=${libraryInstanceId}`,
25
+ rpm: {
26
+ name: __('RPM packages'),
27
+ to: `rpmPackages?repository_id=${libraryInstanceId}`,
28
+ },
29
+ module_stream: {
30
+ name: __('Module streams'),
31
+ to: `moduleStreams?repository_id=${libraryInstanceId}`,
32
+ },
33
+ erratum: {
34
+ name: __('Errata'),
35
+ to: `errata?repository_id=${libraryInstanceId}`,
24
36
  },
25
37
  deb: {
26
38
  name: __('Deb packages'),
27
- url: `debs?repositoryId=${libraryInstanceId}`,
39
+ to: `debPackages?repository_id=${libraryInstanceId}`,
40
+ },
41
+ ansible_collection: {
42
+ name: __('Ansible collections'),
43
+ to: `ansibleCollections?repository_id=${libraryInstanceId}`,
28
44
  },
29
45
  docker_manifest: {
30
46
  name: __('Container manifests'),
31
- url: `products/${id}/repositories/${libraryInstanceId}/content/content/docker_manifests`,
47
+ url: `products/${id}/repositories/${libraryInstanceId}/content/docker_manifests`,
32
48
  },
33
49
  docker_manifest_list: {
34
50
  name: __('Container manifest lists'),
35
- url: `products/${id}/repositories/${libraryInstanceId}/content/content/docker_manifest_lists`,
51
+ url: `products/${id}/repositories/${libraryInstanceId}/content/docker_manifest_lists`,
36
52
  },
37
53
  docker_tag: {
38
54
  name: __('Container image tags'),
39
- url: `docker_tags?repositoryId=${libraryInstanceId}`,
40
- },
41
- erratum: {
42
- name: __('Errata'),
43
- url: `errata?repositoryId=${libraryInstanceId}`,
55
+ to: `dockerTags?repository_id=${libraryInstanceId}`,
44
56
  },
45
57
  file: {
46
58
  name: __('Files'),
47
- url: `files?repositoryId=${libraryInstanceId}`,
48
- },
49
- module_stream: {
50
- name: __('Module streams'),
51
- url: `products/${id}/repositories/${libraryInstanceId}/content/module_streams`,
52
- },
53
- package: {
54
- name: __('Packages'),
55
- url: `products/${id}/repositories/${libraryInstanceId}/content/packages`,
59
+ to: `files?repository_id=${libraryInstanceId}`,
56
60
  },
57
61
  package_group: {
58
62
  name: __('Package groups'),
59
- url: `products/${id}/repositories/${libraryInstanceId}/content/package_groups`,
60
- },
61
- rpm: {
62
- name: __('Rpm packages'),
63
- url: `packages?repositoryId=${libraryInstanceId}`,
63
+ to: `rpmPackageGroups?repository_id=${libraryInstanceId}`,
64
64
  },
65
65
  srpm: {
66
66
  name: __('Source RPMs'),
@@ -70,40 +70,57 @@ const ContentViewVersionRepositoryCell = ({
70
70
  ContentConfig.forEach((type) => {
71
71
  CONTENT_COUNTS[type.names.singularLabel] = {
72
72
  name: type.names.pluralLowercase,
73
- url: `products/${id}/repositories/${libraryInstanceId}/content/${type.names.pluralLabel}`,
73
+ to: `${camelCase(type.names.pluralLabel)}?repository_id=${libraryInstanceId}`,
74
74
  };
75
75
  });
76
76
 
77
77
  const getContentSpan = (num) => {
78
78
  switch (true) {
79
- case num < 4:
80
- return 12;
81
- case num > 4 && num < 9:
82
- return 6;
83
- case num > 9:
84
- return 4;
85
- default:
86
- return 12;
79
+ case num < 4:
80
+ return 12;
81
+ case num > 4 && num < 9:
82
+ return 6;
83
+ case num > 9:
84
+ return 4;
85
+ default:
86
+ return 12;
87
+ }
88
+ };
89
+
90
+ const CountComponent = ({ countKey }) => {
91
+ const { to, url, name } = CONTENT_COUNTS[countKey];
92
+ const count = ContentCounts[countKey];
93
+ switch (true) {
94
+ case !!url:
95
+ return (
96
+ <a href={urlBuilder(url, '')}>
97
+ {count} {name}
98
+ </a>);
99
+ case !!to:
100
+ return (
101
+ <Link to={to}>
102
+ {count} {name}
103
+ </Link>);
104
+ default:
105
+ return `${count} ${name} `;
87
106
  }
88
107
  };
89
108
 
109
+ CountComponent.propTypes = {
110
+ countKey: PropTypes.string.isRequired,
111
+ };
112
+
90
113
  const contentCountArray = Object.keys(CONTENT_COUNTS);
91
114
  const contentCountToShow = contentCountArray.filter(key => !!ContentCounts[key]);
92
115
  const contentSpan = getContentSpan(contentCountToShow.length);
116
+
93
117
  return (
94
118
  <Grid>
95
119
  {!isEmpty(contentCountToShow) ?
96
- contentCountToShow.map((countKey) => {
97
- const { url = undefined, name } = CONTENT_COUNTS[countKey];
98
- const count = ContentCounts[countKey];
99
- return (
100
- <GridItem key={countKey} span={contentSpan}>
101
- {url ?
102
- <a href={urlBuilder(url, '')}>
103
- {count} {name}
104
- </a> : `${count} ${name} `}
105
- </GridItem>);
106
- }) : <InactiveText text={__('N/A')} />
120
+ contentCountToShow.map(countKey => (
121
+ <GridItem key={countKey} span={contentSpan}>
122
+ <CountComponent countKey={countKey} />
123
+ </GridItem>)) : <InactiveText text={__('N/A')} />
107
124
  }
108
125
  </Grid >
109
126
  );
@@ -176,7 +176,7 @@ const testConfig = [
176
176
  last(ContentViewVersionAnsibleCollectionsData.results).checksum],
177
177
  },
178
178
  {
179
- name: 'Docker Tags',
179
+ name: 'Container tags',
180
180
  countKey: 'docker_tag_count',
181
181
  autoCompleteUrl: '/docker_tags/auto_complete_search',
182
182
  dataUrl: api.getApiUrl('/docker_tags'),
@@ -136,8 +136,8 @@ const CVPublishFinish = ({
136
136
  <Bullseye>
137
137
  <Button
138
138
  onClick={() => {
139
- handleEndTask({ taskComplete: false });
140
- }}
139
+ handleEndTask({ taskComplete: false });
140
+ }}
141
141
  variant="primary"
142
142
  aria-label="publish_content_view"
143
143
  >
@@ -166,10 +166,10 @@ const ContentViewTable = () => {
166
166
 
167
167
  const indexToSortVariable = (key) => {
168
168
  switch (key) {
169
- case 2:
170
- return 'name';
171
- default:
172
- return undefined;
169
+ case 2:
170
+ return 'name';
171
+ default:
172
+ return undefined;
173
173
  }
174
174
  };
175
175
 
@@ -5,24 +5,24 @@ const EnvironmentLabels = (environments) => {
5
5
  const { environments: singleEnvironment } = environments || {};
6
6
  const { name } = singleEnvironment || {};
7
7
  switch (environments) {
8
- case Array:
9
- return environments.map(env => (
10
- <React.Fragment key={env.id} style={{ marginBottom: '5px' }}>
11
- <Label
12
- color="purple"
13
- isTruncated
14
- >{env.name}
15
- </Label>
16
- </React.Fragment>
17
- ));
18
- default:
19
- return (
20
- <React.Fragment>
21
- <Label color="purple" isTruncated>
22
- {name}
23
- </Label>
24
- </React.Fragment>
25
- );
8
+ case Array:
9
+ return environments.map(env => (
10
+ <React.Fragment key={env.id} style={{ marginBottom: '5px' }}>
11
+ <Label
12
+ color="purple"
13
+ isTruncated
14
+ >{env.name}
15
+ </Label>
16
+ </React.Fragment>
17
+ ));
18
+ default:
19
+ return (
20
+ <React.Fragment>
21
+ <Label color="purple" isTruncated>
22
+ {name}
23
+ </Label>
24
+ </React.Fragment>
25
+ );
26
26
  }
27
27
  };
28
28