katello 4.9.0.rc2 → 4.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/katello/api/v2/capsule_content_controller.rb +1 -1
- data/app/controllers/katello/api/v2/content_view_versions_controller.rb +1 -4
- data/app/controllers/katello/api/v2/content_views_controller.rb +2 -1
- data/app/controllers/katello/api/v2/organizations_controller.rb +7 -4
- data/app/controllers/katello/api/v2/repositories_controller.rb +4 -4
- data/app/lib/actions/katello/content_view/promote_to_environment.rb +1 -1
- data/app/lib/actions/katello/content_view_version/auto_create_redhat_repositories.rb +2 -1
- data/app/lib/actions/katello/content_view_version/republish_repositories.rb +1 -1
- data/app/lib/actions/katello/orphan_cleanup/remove_orphaned_content_units.rb +22 -0
- data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +4 -15
- data/app/lib/actions/katello/repository/clone_to_version.rb +1 -1
- data/app/lib/actions/katello/repository/multi_clone_to_version.rb +1 -1
- data/app/lib/actions/katello/repository_set/enable_repository.rb +3 -1
- data/app/lib/katello/resources/cdn/katello_cdn.rb +8 -4
- data/app/models/katello/concerns/pulp_database_unit.rb +2 -2
- data/app/models/katello/content_view.rb +7 -0
- data/app/models/katello/repository.rb +0 -1
- data/app/models/katello/root_repository.rb +1 -1
- data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +10 -6
- data/app/services/katello/pulp3/repository/docker.rb +1 -1
- data/app/services/katello/pulp3/repository.rb +4 -2
- data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +12 -11
- data/app/views/katello/api/v2/content_facet/base.json.rabl +9 -10
- data/app/views/katello/hosts/_errata_counts.html.erb +13 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +1 -1
- data/lib/katello/plugin.rb +1 -1
- data/lib/katello/tasks/upgrades/4.9/update_custom_products_enablement.rake +4 -2
- data/lib/katello/version.rb +1 -1
- data/webpack/components/RoutedTabs/index.js +1 -0
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +2 -2
- data/webpack/components/extensions/HostDetails/Tabs/ContentTab/index.js +1 -0
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +1 -1
- data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +3 -3
- data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +3 -3
- data/webpack/redux/actions/RedHatRepositories/helpers.js +3 -5
- data/webpack/scenes/Content/Details/ContentRepositories.js +1 -1
- data/webpack/scenes/Content/Table/ContentTable.js +1 -1
- data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +1 -14
- data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +0 -4
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentEnvironments.js +1 -1
- data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +1 -1
- data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +41 -32
- data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +32 -26
- data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +10 -2
- data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +10 -2
- data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +10 -2
- data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +10 -2
- data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +10 -2
- data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +10 -2
- data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +10 -2
- data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +2 -2
- data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +3 -3
- data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompare.js +1 -0
- data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +1 -1
- data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +1 -1
- data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +1 -0
- data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +7 -0
- data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetail.test.js +28 -4
- data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetails.fixtures.json +1 -0
- data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +13 -2
- data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +4 -1
- data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +33 -10
- data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +0 -2
- data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +1 -1
- data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +7 -2
- data/webpack/scenes/Subscriptions/Manifest/DeleteManifestModalText.js +38 -21
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +19 -4
- data/webpack/scenes/Subscriptions/SubscriptionsPage.js +1 -0
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +1 -0
- metadata +10 -9
|
@@ -24,7 +24,6 @@ const recommendedRepositoriesRHEL = [
|
|
|
24
24
|
'rhel-7-server-optional-rpms',
|
|
25
25
|
'rhel-7-server-extras-rpms',
|
|
26
26
|
'rhel-7-server-kickstart',
|
|
27
|
-
'rhel-6-server-els-rpms',
|
|
28
27
|
];
|
|
29
28
|
|
|
30
29
|
const recommendedRepositoriesSatTools = [
|
|
@@ -35,10 +34,9 @@ const recommendedRepositoriesSatTools = [
|
|
|
35
34
|
];
|
|
36
35
|
|
|
37
36
|
const recommendedRepositoriesMisc = [
|
|
38
|
-
'satellite-capsule-6.
|
|
39
|
-
'
|
|
40
|
-
'satellite-
|
|
41
|
-
'satellite-utils-6.13-for-rhel-8-x86_64-rpms',
|
|
37
|
+
'satellite-capsule-6.14-for-rhel-8-x86_64-rpms',
|
|
38
|
+
'satellite-maintenance-6.14-for-rhel-8-x86_64-rpms',
|
|
39
|
+
'satellite-utils-6.14-for-rhel-8-x86_64-rpms',
|
|
42
40
|
];
|
|
43
41
|
|
|
44
42
|
const recommendedRepositorySetLables = recommendedRepositoriesRHEL
|
|
@@ -59,7 +59,7 @@ const ContentRepositories = ({ contentType, id, tabKey }) => {
|
|
|
59
59
|
</Thead>
|
|
60
60
|
<Tbody>
|
|
61
61
|
{results?.map((details, idx) => (
|
|
62
|
-
<Tr key={
|
|
62
|
+
<Tr key={details.id} ouiaId={`content-repositories-row-${idx}`}>
|
|
63
63
|
{columnHeaders.map((col, index) =>
|
|
64
64
|
<Td key={index}>{col.getProperty(details, typeSingularLabel)}</Td>)
|
|
65
65
|
}
|
|
@@ -65,7 +65,7 @@ const ContentTable = ({
|
|
|
65
65
|
</Thead>
|
|
66
66
|
<Tbody>
|
|
67
67
|
{results?.map(details => (
|
|
68
|
-
<Tr key={
|
|
68
|
+
<Tr key={details.id} ouiaId={`${details.id}-tr`}>
|
|
69
69
|
{columnHeaders.map((col, index) =>
|
|
70
70
|
<Td key={index}>{col.getProperty(details)}</Td>)
|
|
71
71
|
}
|
|
@@ -7,7 +7,7 @@ import { useDispatch, useSelector } from 'react-redux';
|
|
|
7
7
|
import { Form, FormGroup, TextInput, TextArea, Checkbox, ActionGroup, Button, Tile, Grid, GridItem } from '@patternfly/react-core';
|
|
8
8
|
import { createContentView } from '../ContentViewsActions';
|
|
9
9
|
import { selectCreateContentViews, selectCreateContentViewStatus, selectCreateContentViewError } from './ContentViewCreateSelectors';
|
|
10
|
-
import { LabelDependencies, LabelAutoPublish
|
|
10
|
+
import { LabelDependencies, LabelAutoPublish } from './ContentViewFormComponents';
|
|
11
11
|
import ContentViewIcon from '../components/ContentViewIcon';
|
|
12
12
|
import './CreateContentViewForm.scss';
|
|
13
13
|
|
|
@@ -19,7 +19,6 @@ const CreateContentViewForm = ({ setModalOpen }) => {
|
|
|
19
19
|
const [composite, setComposite] = useState(false);
|
|
20
20
|
const [component, setComponent] = useState(true);
|
|
21
21
|
const [autoPublish, setAutoPublish] = useState(false);
|
|
22
|
-
const [importOnly, setImportOnly] = useState(false);
|
|
23
22
|
const [dependencies, setDependencies] = useState(false);
|
|
24
23
|
const [redirect, setRedirect] = useState(false);
|
|
25
24
|
const [saving, setSaving] = useState(false);
|
|
@@ -59,7 +58,6 @@ const CreateContentViewForm = ({ setModalOpen }) => {
|
|
|
59
58
|
composite,
|
|
60
59
|
solve_dependencies: dependencies,
|
|
61
60
|
auto_publish: (autoPublish && composite),
|
|
62
|
-
import_only: importOnly,
|
|
63
61
|
}));
|
|
64
62
|
};
|
|
65
63
|
|
|
@@ -168,17 +166,6 @@ const CreateContentViewForm = ({ setModalOpen }) => {
|
|
|
168
166
|
onChange={checked => setDependencies(checked)}
|
|
169
167
|
/>
|
|
170
168
|
</FormGroup>}
|
|
171
|
-
{!composite &&
|
|
172
|
-
<FormGroup isInline fieldId="importOnly">
|
|
173
|
-
<Checkbox
|
|
174
|
-
id="importOnly"
|
|
175
|
-
ouiaId="importOnly"
|
|
176
|
-
name="importOnly"
|
|
177
|
-
label={LabelImportOnly()}
|
|
178
|
-
isChecked={importOnly}
|
|
179
|
-
onChange={checked => setImportOnly(checked)}
|
|
180
|
-
/>
|
|
181
|
-
</FormGroup>}
|
|
182
169
|
{composite &&
|
|
183
170
|
<FormGroup isInline fieldId="autoPublish">
|
|
184
171
|
<Checkbox
|
|
@@ -24,7 +24,6 @@ const createDetails = {
|
|
|
24
24
|
composite: false,
|
|
25
25
|
solve_dependencies: false,
|
|
26
26
|
auto_publish: false,
|
|
27
|
-
import_only: false,
|
|
28
27
|
};
|
|
29
28
|
|
|
30
29
|
const createdCVDetails = { ...cvCreateData };
|
|
@@ -78,7 +77,6 @@ test('Displays dependent fields correctly', () => {
|
|
|
78
77
|
expect(getByText('Content view')).toBeInTheDocument();
|
|
79
78
|
expect(getByText('Solve dependencies')).toBeInTheDocument();
|
|
80
79
|
expect(queryByText('Auto publish')).not.toBeInTheDocument();
|
|
81
|
-
expect(getByText('Import only')).toBeInTheDocument();
|
|
82
80
|
|
|
83
81
|
// label auto_set
|
|
84
82
|
fireEvent.change(getByLabelText('input_name'), { target: { value: '123 2123' } });
|
|
@@ -88,13 +86,11 @@ test('Displays dependent fields correctly', () => {
|
|
|
88
86
|
fireEvent.click(getByLabelText('composite_tile'));
|
|
89
87
|
expect(queryByText('Solve dependencies')).not.toBeInTheDocument();
|
|
90
88
|
expect(getByText('Auto publish')).toBeInTheDocument();
|
|
91
|
-
expect(queryByText('Import only')).not.toBeInTheDocument();
|
|
92
89
|
|
|
93
90
|
// display Solve Dependencies when Component CV
|
|
94
91
|
fireEvent.click(getByLabelText('component_tile'));
|
|
95
92
|
expect(getByText('Solve dependencies')).toBeInTheDocument();
|
|
96
93
|
expect(queryByText('Auto publish')).not.toBeInTheDocument();
|
|
97
|
-
expect(getByText('Import only')).toBeInTheDocument();
|
|
98
94
|
});
|
|
99
95
|
|
|
100
96
|
test('Validates label field', () => {
|
|
@@ -592,7 +592,7 @@ export const republishCVVRepoMetadata = (params, handleSuccess) => put({
|
|
|
592
592
|
type: API_OPERATIONS.PUT,
|
|
593
593
|
key: cvVersionRepublishRepoMetadataKey(params.cvId, params.id),
|
|
594
594
|
url: api.getApiUrl(`/content_view_versions/${params.id}/republish_repositories`),
|
|
595
|
-
params
|
|
595
|
+
params,
|
|
596
596
|
handleSuccess: (response) => {
|
|
597
597
|
if (handleSuccess) return handleSuccess();
|
|
598
598
|
return renderTaskStartedToast(response.data);
|
|
@@ -37,7 +37,7 @@ import { hasPermission } from '../helpers';
|
|
|
37
37
|
import CopyContentViewModal from '../Copy/CopyContentViewModal';
|
|
38
38
|
import ContentViewDeleteWizard from '../Delete/ContentViewDeleteWizard';
|
|
39
39
|
import EmptyStateMessage from '../../../components/Table/EmptyStateMessage';
|
|
40
|
-
import { cvVersionTaskPollingKey } from '../ContentViewsConstants';
|
|
40
|
+
import { CONTENT_VIEW_NEEDS_PUBLISH_RESET, cvVersionTaskPollingKey } from '../ContentViewsConstants';
|
|
41
41
|
import { clearPollTaskData, stopPollingTask } from '../../Tasks/TaskActions';
|
|
42
42
|
|
|
43
43
|
export default () => {
|
|
@@ -73,6 +73,7 @@ export default () => {
|
|
|
73
73
|
|
|
74
74
|
useEffect(() => {
|
|
75
75
|
dispatch(getContentViewDetails(cvId));
|
|
76
|
+
dispatch({ type: CONTENT_VIEW_NEEDS_PUBLISH_RESET });
|
|
76
77
|
}, [cvId, dispatch]);
|
|
77
78
|
|
|
78
79
|
|
|
@@ -105,39 +106,47 @@ export default () => {
|
|
|
105
106
|
generated_for: generatedFor, import_only: importOnly,
|
|
106
107
|
} = details;
|
|
107
108
|
const generatedContentView = generatedFor !== 'none';
|
|
109
|
+
const detailsTab = {
|
|
110
|
+
key: 'details',
|
|
111
|
+
title: __('Details'),
|
|
112
|
+
content: <ContentViewInfo {...{ cvId, details }} />,
|
|
113
|
+
};
|
|
114
|
+
const versionsTab = {
|
|
115
|
+
key: 'versions',
|
|
116
|
+
title: __('Versions'),
|
|
117
|
+
content: <ContentViewVersionsRoutes {...{ cvId, details }} />,
|
|
118
|
+
};
|
|
119
|
+
const contentViewsTab = {
|
|
120
|
+
key: 'contentviews',
|
|
121
|
+
title: __('Content views'),
|
|
122
|
+
content: <ContentViewComponents {...{ cvId, details }} />,
|
|
123
|
+
};
|
|
124
|
+
const repositoriesTab = {
|
|
125
|
+
key: 'repositories',
|
|
126
|
+
title: __('Repositories'),
|
|
127
|
+
content: <ContentViewRepositories {...{ cvId, details }} />,
|
|
128
|
+
};
|
|
129
|
+
const filtersTab = {
|
|
130
|
+
key: 'filters',
|
|
131
|
+
title: __('Filters'),
|
|
132
|
+
content: <ContentViewFilterRoutes {...{ cvId, details }} />,
|
|
133
|
+
};
|
|
134
|
+
const historyTab = {
|
|
135
|
+
key: 'history',
|
|
136
|
+
title: __('History'),
|
|
137
|
+
content: <ContentViewHistories cvId={cvId} />,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/* eslint-disable no-nested-ternary */
|
|
108
141
|
const tabs = [
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
key: 'versions',
|
|
116
|
-
title: __('Versions'),
|
|
117
|
-
content: <ContentViewVersionsRoutes {...{ cvId, details }} />,
|
|
118
|
-
},
|
|
119
|
-
...composite ? [{
|
|
120
|
-
key: 'contentviews',
|
|
121
|
-
title: __('Content views'),
|
|
122
|
-
content: <ContentViewComponents {...{ cvId, details }} />,
|
|
123
|
-
}] : [{
|
|
124
|
-
key: 'repositories',
|
|
125
|
-
title: __('Repositories'),
|
|
126
|
-
content: <ContentViewRepositories {...{ cvId, details }} />,
|
|
127
|
-
},
|
|
128
|
-
!(importOnly || generatedContentView) &&
|
|
129
|
-
{
|
|
130
|
-
key: 'filters',
|
|
131
|
-
title: __('Filters'),
|
|
132
|
-
content: <ContentViewFilterRoutes {...{ cvId, details }} />,
|
|
133
|
-
}],
|
|
134
|
-
{
|
|
135
|
-
key: 'history',
|
|
136
|
-
title: __('History'),
|
|
137
|
-
content: <ContentViewHistories cvId={cvId} />,
|
|
138
|
-
},
|
|
142
|
+
detailsTab,
|
|
143
|
+
versionsTab,
|
|
144
|
+
...(composite ? [contentViewsTab] :
|
|
145
|
+
((importOnly || generatedContentView) ?
|
|
146
|
+
[repositoriesTab] : [repositoriesTab, filtersTab])),
|
|
147
|
+
historyTab,
|
|
139
148
|
];
|
|
140
|
-
|
|
149
|
+
/* eslint-enable no-nested-ternary */
|
|
141
150
|
|
|
142
151
|
return (
|
|
143
152
|
<>
|
|
@@ -111,32 +111,38 @@ const ContentViewInfo = ({ cvId, details }) => {
|
|
|
111
111
|
boolean
|
|
112
112
|
{...{ currentAttribute, setCurrentAttribute }}
|
|
113
113
|
/>)}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
114
|
+
{importOnly &&
|
|
115
|
+
<>
|
|
116
|
+
<TextListItem component={TextListItemVariants.dt}>
|
|
117
|
+
{LabelImportOnly()}
|
|
118
|
+
</TextListItem>
|
|
119
|
+
<TextListItem component={TextListItemVariants.dd} className="foreman-spaced-list">
|
|
120
|
+
<Switch
|
|
121
|
+
id="import_only_switch"
|
|
122
|
+
ouiaId="import_only_switch"
|
|
123
|
+
aria-label="import_only_switch"
|
|
124
|
+
isChecked={importOnly}
|
|
125
|
+
className="foreman-spaced-list"
|
|
126
|
+
disabled
|
|
127
|
+
/>
|
|
128
|
+
</TextListItem>
|
|
129
|
+
</>}
|
|
130
|
+
{generatedContentView &&
|
|
131
|
+
<>
|
|
132
|
+
<TextListItem component={TextListItemVariants.dt}>
|
|
133
|
+
{LabelGenerated()}
|
|
134
|
+
</TextListItem>
|
|
135
|
+
<TextListItem component={TextListItemVariants.dd} className="foreman-spaced-list">
|
|
136
|
+
<Switch
|
|
137
|
+
id="generated_by_export_switch"
|
|
138
|
+
ouiaId="generated_by_export_switch"
|
|
139
|
+
aria-label="generated_by_export_switch"
|
|
140
|
+
isChecked={generatedContentView}
|
|
141
|
+
className="foreman-spaced-list"
|
|
142
|
+
disabled
|
|
143
|
+
/>
|
|
144
|
+
</TextListItem>
|
|
145
|
+
</>}
|
|
140
146
|
</TextList>
|
|
141
147
|
</TextContent>
|
|
142
148
|
);
|
|
@@ -135,7 +135,11 @@ const CVContainerImageFilterContent = ({
|
|
|
135
135
|
ouiaId="cv-container-image-filter-tabs"
|
|
136
136
|
onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
|
|
137
137
|
>
|
|
138
|
-
<Tab
|
|
138
|
+
<Tab
|
|
139
|
+
ouiaId="cv-container-image-filter-tags-tab"
|
|
140
|
+
eventKey={0}
|
|
141
|
+
title={<TabTitleText>{__('Tags')}</TabTitleText>}
|
|
142
|
+
>
|
|
139
143
|
<div className="margin-24-0">
|
|
140
144
|
<TableWrapper
|
|
141
145
|
{...{
|
|
@@ -200,7 +204,11 @@ const CVContainerImageFilterContent = ({
|
|
|
200
204
|
</div>
|
|
201
205
|
</Tab>
|
|
202
206
|
{(repositories.length || showAffectedRepos) &&
|
|
203
|
-
<Tab
|
|
207
|
+
<Tab
|
|
208
|
+
ouiaId="cv-container-image-affected-repos-tab"
|
|
209
|
+
eventKey={1}
|
|
210
|
+
title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
|
|
211
|
+
>
|
|
204
212
|
<div className="margin-24-0">
|
|
205
213
|
<AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="docker" setShowAffectedRepos={setShowAffectedRepos} details={details} />
|
|
206
214
|
</div>
|
|
@@ -150,7 +150,11 @@ const CVDebFilterContent = ({
|
|
|
150
150
|
activeKey={activeTabKey}
|
|
151
151
|
onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
|
|
152
152
|
>
|
|
153
|
-
<Tab
|
|
153
|
+
<Tab
|
|
154
|
+
ouiaId="cv-deb-filter-content-table-tab"
|
|
155
|
+
eventKey={0}
|
|
156
|
+
title={<TabTitleText>{tabTitle}</TabTitleText>}
|
|
157
|
+
>
|
|
154
158
|
<div className="tab-body-with-spacing">
|
|
155
159
|
<TableWrapper
|
|
156
160
|
{...{
|
|
@@ -225,7 +229,11 @@ const CVDebFilterContent = ({
|
|
|
225
229
|
</div>
|
|
226
230
|
</Tab>
|
|
227
231
|
{(repositories.length || showAffectedRepos) &&
|
|
228
|
-
<Tab
|
|
232
|
+
<Tab
|
|
233
|
+
ouiaId="cv-deb-filter-content-affected-repos-tab"
|
|
234
|
+
eventKey={1}
|
|
235
|
+
title={<TabTitleText>{__('Affected Repositories')}</TabTitleText>}
|
|
236
|
+
>
|
|
229
237
|
<div className="tab-body-with-spacing">
|
|
230
238
|
<AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="deb" setShowAffectedRepos={setShowAffectedRepos} details={details} />
|
|
231
239
|
</div>
|
|
@@ -119,7 +119,11 @@ const CVErrataDateFilterContent = ({
|
|
|
119
119
|
activeKey={activeTabKey}
|
|
120
120
|
onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
|
|
121
121
|
>
|
|
122
|
-
<Tab
|
|
122
|
+
<Tab
|
|
123
|
+
ouiaId="errata-date-filter-form-tab"
|
|
124
|
+
eventKey={0}
|
|
125
|
+
title={<TabTitleText>{tabTitle}</TabTitleText>}
|
|
126
|
+
>
|
|
123
127
|
<div className="margin-24">
|
|
124
128
|
<Form onSubmit={(e) => {
|
|
125
129
|
e.preventDefault();
|
|
@@ -309,7 +313,11 @@ const CVErrataDateFilterContent = ({
|
|
|
309
313
|
</div>
|
|
310
314
|
</Tab>
|
|
311
315
|
{(repositories.length || showAffectedRepos) &&
|
|
312
|
-
<Tab
|
|
316
|
+
<Tab
|
|
317
|
+
ouiaId="affected-repositories-tab"
|
|
318
|
+
eventKey={1}
|
|
319
|
+
title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
|
|
320
|
+
>
|
|
313
321
|
<div className="margin-24-0">
|
|
314
322
|
<AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
|
|
315
323
|
</div>
|
|
@@ -251,7 +251,11 @@ const CVErrataIDFilterContent = ({
|
|
|
251
251
|
activeKey={activeTabKey}
|
|
252
252
|
onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
|
|
253
253
|
>
|
|
254
|
-
<Tab
|
|
254
|
+
<Tab
|
|
255
|
+
ouiaId="errata-filter-table-tab"
|
|
256
|
+
eventKey={0}
|
|
257
|
+
title={<TabTitleText>{__('Errata')}</TabTitleText>}
|
|
258
|
+
>
|
|
255
259
|
<div className="margin-24-0">
|
|
256
260
|
<TableWrapper
|
|
257
261
|
{...{
|
|
@@ -452,7 +456,11 @@ const CVErrataIDFilterContent = ({
|
|
|
452
456
|
</div>
|
|
453
457
|
</Tab>
|
|
454
458
|
{(repositories.length || showAffectedRepos) &&
|
|
455
|
-
<Tab
|
|
459
|
+
<Tab
|
|
460
|
+
ouiaId="affected-repos-tab"
|
|
461
|
+
eventKey={1}
|
|
462
|
+
title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
|
|
463
|
+
>
|
|
456
464
|
<div className="margin-24-0">
|
|
457
465
|
<AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
|
|
458
466
|
</div>
|
|
@@ -207,7 +207,11 @@ const CVModuleStreamFilterContent = ({
|
|
|
207
207
|
activeKey={activeTabKey}
|
|
208
208
|
onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
|
|
209
209
|
>
|
|
210
|
-
<Tab
|
|
210
|
+
<Tab
|
|
211
|
+
ouiaId="module-stream-filter-content-table-tab"
|
|
212
|
+
eventKey={0}
|
|
213
|
+
title={<TabTitleText>{__('Module Streams')}</TabTitleText>}
|
|
214
|
+
>
|
|
211
215
|
<div className="margin-24-0">
|
|
212
216
|
<TableWrapper
|
|
213
217
|
{...{
|
|
@@ -285,7 +289,11 @@ const CVModuleStreamFilterContent = ({
|
|
|
285
289
|
</div>
|
|
286
290
|
</Tab>
|
|
287
291
|
{(repositories.length || showAffectedRepos) &&
|
|
288
|
-
<Tab
|
|
292
|
+
<Tab
|
|
293
|
+
ouiaId="affected-repos-tab"
|
|
294
|
+
eventKey={1}
|
|
295
|
+
title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
|
|
296
|
+
>
|
|
289
297
|
<div className="margin-24-0">
|
|
290
298
|
<AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
|
|
291
299
|
</div>
|
|
@@ -197,7 +197,11 @@ const CVPackageGroupFilterContent = ({
|
|
|
197
197
|
activeKey={activeTabKey}
|
|
198
198
|
onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
|
|
199
199
|
>
|
|
200
|
-
<Tab
|
|
200
|
+
<Tab
|
|
201
|
+
ouiaId="cv-package-group-filter-content-table-tab"
|
|
202
|
+
eventKey={0}
|
|
203
|
+
title={<TabTitleText>{__('Package groups')}</TabTitleText>}
|
|
204
|
+
>
|
|
201
205
|
<div className="margin-24-0">
|
|
202
206
|
<TableWrapper
|
|
203
207
|
{...{
|
|
@@ -275,7 +279,11 @@ const CVPackageGroupFilterContent = ({
|
|
|
275
279
|
</div>
|
|
276
280
|
</Tab>
|
|
277
281
|
{(repositories.length || showAffectedRepos) &&
|
|
278
|
-
<Tab
|
|
282
|
+
<Tab
|
|
283
|
+
ouiaId="affected-repos-tab"
|
|
284
|
+
eventKey={1}
|
|
285
|
+
title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
|
|
286
|
+
>
|
|
279
287
|
<div className="margin-24-0">
|
|
280
288
|
<AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
|
|
281
289
|
</div>
|
|
@@ -167,7 +167,11 @@ const CVRpmFilterContent = ({
|
|
|
167
167
|
activeKey={activeTabKey}
|
|
168
168
|
onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
|
|
169
169
|
>
|
|
170
|
-
<Tab
|
|
170
|
+
<Tab
|
|
171
|
+
ouiaId="cv-rpm-filter-content-table-tab"
|
|
172
|
+
eventKey={0}
|
|
173
|
+
title={<TabTitleText>{tabTitle}</TabTitleText>}
|
|
174
|
+
>
|
|
171
175
|
<div className="margin-24-0">
|
|
172
176
|
<TableWrapper
|
|
173
177
|
{...{
|
|
@@ -239,7 +243,11 @@ const CVRpmFilterContent = ({
|
|
|
239
243
|
</div>
|
|
240
244
|
</Tab>
|
|
241
245
|
{(repositories.length || showAffectedRepos) &&
|
|
242
|
-
<Tab
|
|
246
|
+
<Tab
|
|
247
|
+
ouiaId="cv-rpm-filter-content-affected-repos-tab"
|
|
248
|
+
eventKey={1}
|
|
249
|
+
title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
|
|
250
|
+
>
|
|
243
251
|
<div className="margin-24-0">
|
|
244
252
|
<AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
|
|
245
253
|
</div>
|
|
@@ -49,9 +49,9 @@ const ContentViewHistories = ({ cvId }) => {
|
|
|
49
49
|
const taskType = task ? task.label : taskTypes[action];
|
|
50
50
|
|
|
51
51
|
if (taskType === taskTypes.removal) {
|
|
52
|
-
return <>{__('Deleted from ')} <Label isTruncated key="1" color="blue" href={`/lifecycle_environments/${environment?.id}`}>{
|
|
52
|
+
return <>{__('Deleted from ')} <Label isTruncated key="1" color="blue" href={`/lifecycle_environments/${environment?.id}`}>{environment?.name ?? __('all environments')}</Label></>;
|
|
53
53
|
} else if (action === 'promotion' || taskType === taskTypes.promotion) {
|
|
54
|
-
return <>{__('Promoted to ')}<Label isTruncated key="2" color="blue" href={`/lifecycle_environments/${environment?.id}`}>{
|
|
54
|
+
return <>{__('Promoted to ')}<Label isTruncated key="2" color="blue" href={`/lifecycle_environments/${environment?.id}`}>{environment?.name}</Label></>;
|
|
55
55
|
} else if (taskType === taskTypes.publish) {
|
|
56
56
|
return __('Published new version');
|
|
57
57
|
} else if (taskType === taskTypes.export) {
|
|
@@ -12,9 +12,9 @@ const repoLabels = {
|
|
|
12
12
|
erratum: ['errata', 'erratum', 'errata'], // need to handle link, its $URL/errata?repositoryId=107
|
|
13
13
|
deb: ['deb packages', 'deb package', 'debs'],
|
|
14
14
|
ansible_collection: ['Ansible collections', 'Ansible collection', 'ansible_collections'],
|
|
15
|
-
docker_manifest: ['container manifests', 'container manifest', '
|
|
16
|
-
docker_manifest_list: ['container manifest lists', 'container manifest list', '
|
|
17
|
-
docker_tag: ['container tags', 'container tag', '
|
|
15
|
+
docker_manifest: ['container manifests', 'container manifest', 'docker_manifests'],
|
|
16
|
+
docker_manifest_list: ['container manifest lists', 'container manifest list', 'docker_manifest_lists'],
|
|
17
|
+
docker_tag: ['container tags', 'container tag', 'docker_tags'],
|
|
18
18
|
file: ['files', 'file', 'content/files'],
|
|
19
19
|
package_group: ['package groups', 'package group', 'package_groups'],
|
|
20
20
|
srpm: ['source RPMs', 'source RPM', 'source_rpms'], // no link?
|
|
@@ -66,7 +66,7 @@ const AffectedActivationKeys = ({
|
|
|
66
66
|
</Thead>
|
|
67
67
|
<Tbody>
|
|
68
68
|
{results?.map(({ name, id, environment }) => (
|
|
69
|
-
<Tr ouiaId={
|
|
69
|
+
<Tr ouiaId={id} key={id}>
|
|
70
70
|
<Td>
|
|
71
71
|
<a rel="noreferrer" target="_blank" href={urlBuilder(`activation_keys/${id}`, '')}>{name}</a>
|
|
72
72
|
</Td>
|
|
@@ -65,7 +65,7 @@ const AffectedHosts = ({
|
|
|
65
65
|
id,
|
|
66
66
|
content_facet_attributes: { lifecycle_environment: environment },
|
|
67
67
|
}) => (
|
|
68
|
-
<Tr ouiaId={
|
|
68
|
+
<Tr ouiaId={id} key={id}>
|
|
69
69
|
<Td>
|
|
70
70
|
<a rel="noreferrer" target="_blank" href={urlBuilder(`new/hosts/${id}`, '')}>{name}</a>
|
|
71
71
|
</Td>
|
|
@@ -13,6 +13,7 @@ import contentViewTaskResponseData from './contentViewTaskResponse.fixtures.json
|
|
|
13
13
|
import cvDetailData from '../../../../ContentViews/__tests__/mockDetails.fixtures.json';
|
|
14
14
|
import environmentPathsData from '../../../Publish/__tests__/environmentPaths.fixtures.json';
|
|
15
15
|
import cvIndexData from '../../../__tests__/contentViewList.fixtures.json';
|
|
16
|
+
import contentViewFilterData from '../../Filters/__tests__/contentViewFilters.fixtures.json';
|
|
16
17
|
|
|
17
18
|
const cvPromotePath = api.getApiUrl('/content_view_versions/10/promote');
|
|
18
19
|
const cvIndexPath = api.getApiUrl('/content_views');
|
|
@@ -34,6 +35,7 @@ const renderOptions = {
|
|
|
34
35
|
const cvVersions = api.getApiUrl('/content_view_versions');
|
|
35
36
|
const autocompleteUrl = '/content_view_versions/auto_complete_search';
|
|
36
37
|
const taskPollingUrl = '/foreman_tasks/api/tasks/6b900ff8-62bb-42ac-8c45-da86b7258520';
|
|
38
|
+
const cvFiltersPath = api.getApiUrl('/content_view_filters?content_view_id=5');
|
|
37
39
|
|
|
38
40
|
let firstVersion;
|
|
39
41
|
let envScope;
|
|
@@ -330,6 +332,10 @@ test('Shows call-to-action when there are no versions', async (done) => {
|
|
|
330
332
|
.query(true)
|
|
331
333
|
.reply(200, environmentPathsData);
|
|
332
334
|
|
|
335
|
+
const filterScope = nockInstance
|
|
336
|
+
.get(cvFiltersPath)
|
|
337
|
+
.reply(200, contentViewFilterData);
|
|
338
|
+
|
|
333
339
|
const { getByText, queryByText } = renderWithRedux(
|
|
334
340
|
withCVRoute(<ContentViewVersions cvId={5} details={cvDetailData} />),
|
|
335
341
|
renderOptions,
|
|
@@ -347,6 +353,7 @@ test('Shows call-to-action when there are no versions', async (done) => {
|
|
|
347
353
|
assertNockRequest(scopeWizard);
|
|
348
354
|
assertNockRequest(autocompleteScope);
|
|
349
355
|
assertNockRequest(scope);
|
|
356
|
+
assertNockRequest(filterScope);
|
|
350
357
|
act(done);
|
|
351
358
|
});
|
|
352
359
|
|
|
@@ -28,7 +28,7 @@ test('Can call API and show details on page load', async (done) => {
|
|
|
28
28
|
.query(true)
|
|
29
29
|
.reply(200, cvDetailData);
|
|
30
30
|
|
|
31
|
-
const { getByLabelText } = renderWithRedux(
|
|
31
|
+
const { getByLabelText, queryByLabelText } = renderWithRedux(
|
|
32
32
|
withCVRoute(<ContentViewDetails />),
|
|
33
33
|
renderOptions,
|
|
34
34
|
);
|
|
@@ -40,6 +40,8 @@ test('Can call API and show details on page load', async (done) => {
|
|
|
40
40
|
expect(getByLabelText('a_cv_index')).toBeInTheDocument();
|
|
41
41
|
expect(getByLabelText(`b_${name}`)).toBeInTheDocument();
|
|
42
42
|
expect(getByLabelText('c_details')).toBeInTheDocument();
|
|
43
|
+
expect(queryByLabelText('Import only')).not.toBeInTheDocument();
|
|
44
|
+
expect(queryByLabelText('Generated')).not.toBeInTheDocument();
|
|
43
45
|
});
|
|
44
46
|
|
|
45
47
|
assertNockRequest(scope, done);
|
|
@@ -98,7 +100,7 @@ test('Can edit boolean details such as solve dependencies', async (done) => {
|
|
|
98
100
|
.query(true)
|
|
99
101
|
.reply(200, updatedCVDetails);
|
|
100
102
|
|
|
101
|
-
const { getByLabelText } = renderWithRedux(
|
|
103
|
+
const { getByLabelText, queryByLabelText } = renderWithRedux(
|
|
102
104
|
withCVRoute(<ContentViewDetails />),
|
|
103
105
|
renderOptions,
|
|
104
106
|
);
|
|
@@ -110,8 +112,7 @@ test('Can edit boolean details such as solve dependencies', async (done) => {
|
|
|
110
112
|
await patientlyWaitFor(() => expect(getByLabelText(checkboxLabel).checked).toBeTruthy());
|
|
111
113
|
|
|
112
114
|
const disabledImportLabel = /import_only_switch/;
|
|
113
|
-
expect(
|
|
114
|
-
expect(getByLabelText(disabledImportLabel)).toHaveAttribute('disabled');
|
|
115
|
+
expect(queryByLabelText(disabledImportLabel)).not.toBeInTheDocument();
|
|
115
116
|
|
|
116
117
|
assertNockRequest(getscope);
|
|
117
118
|
assertNockRequest(updatescope);
|
|
@@ -137,3 +138,26 @@ test('Can link to view tasks', async () => {
|
|
|
137
138
|
|
|
138
139
|
assertNockRequest(scope);
|
|
139
140
|
});
|
|
141
|
+
|
|
142
|
+
test('Can show import_only and generated when true', async (done) => {
|
|
143
|
+
const updatedCVDetails = { ...cvDetailData };
|
|
144
|
+
updatedCVDetails.generated_for = 'Library';
|
|
145
|
+
updatedCVDetails.import_only = true;
|
|
146
|
+
|
|
147
|
+
const scope = nockInstance
|
|
148
|
+
.get(cvDetailsPath)
|
|
149
|
+
.query(true)
|
|
150
|
+
.reply(200, updatedCVDetails);
|
|
151
|
+
|
|
152
|
+
const { getByLabelText } = renderWithRedux(
|
|
153
|
+
withCVRoute(<ContentViewDetails />),
|
|
154
|
+
renderOptions,
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
await patientlyWaitFor(() => {
|
|
158
|
+
expect(getByLabelText('import_only_switch')).toBeInTheDocument();
|
|
159
|
+
expect(getByLabelText('generated_by_export_switch')).toBeInTheDocument();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
assertNockRequest(scope, done);
|
|
163
|
+
});
|