Skip to content

Commit f2c0e86

Browse files
committed
Fixes #38191: Skip reassignment for multiCV in remove
1 parent 871b862 commit f2c0e86

File tree

4 files changed

+83
-24
lines changed

4 files changed

+83
-24
lines changed

app/views/katello/api/v2/content_view_versions/base.json.rabl

+12
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,21 @@ child :sorted_organization_readable_environments => :environments do
7373
::Host.authorized('view_hosts').in_content_view_environment(:content_view => version.content_view, :lifecycle_environment => env).count
7474
end
7575

76+
node :multi_env_host_count do |env|
77+
hosts = ::Host.authorized('view_hosts')
78+
.in_content_view_environments(content_views: [version.content_view], lifecycle_environments: [env])
79+
hosts.count { |host| host.content_facet.multi_content_view_environment? }
80+
end
81+
7682
node :activation_key_count do |env|
7783
Katello::ActivationKey.with_content_views(version.content_view).with_environments(env).count
7884
end
85+
86+
node :multi_env_ak_count do |env|
87+
keys = Katello::ActivationKey.with_content_views(version.content_view)
88+
.with_environments(env)
89+
keys.count { |key| key.multi_content_view_environment? }
90+
end
7991
end
8092

8193
child :archived_repos => :repositories do

webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVEnvironmentSelectionForm.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,15 @@ const CVEnvironmentSelectionForm = () => {
2525

2626
// Based on env selected for removal, decide if we need to reassign hosts and activation keys.
2727
useDeepCompareEffect(() => {
28-
const selectedEnv = versionEnvironments.filter(env => selectedEnvSet.has(env.id));
29-
setAffectedActivationKeys(!!(selectedEnv.filter(env => env.activation_key_count > 0).length));
30-
setAffectedHosts(!!(selectedEnv.filter(env => env.host_count > 0).length));
28+
const selectedEnvironments = versionEnvironments.filter(env => selectedEnvSet.has(env.id));
29+
30+
const needsHostReassignment = selectedEnvironments.some(env =>
31+
(env.host_count || 0) > (env.multi_env_host_count || 0));
32+
setAffectedHosts(needsHostReassignment);
33+
34+
const needsAKReassignment = selectedEnvironments.some(env =>
35+
(env.activation_key_count || 0) > (env.multi_env_ak_count || 0));
36+
setAffectedActivationKeys(needsAKReassignment);
3137
}, [setAffectedActivationKeys, setAffectedHosts,
3238
versionEnvironments, selectedEnvSet, selectedEnvSet.size]);
3339

webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionRemoveReview.js

+49-18
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import React, { useContext, useState } from 'react';
22
import { useSelector } from 'react-redux';
3-
import { Alert, Flex, FlexItem, Label, AlertActionCloseButton } from '@patternfly/react-core';
3+
import { Alert, Flex, FlexItem, Label, AlertActionCloseButton, ExpandableSection } from '@patternfly/react-core';
44
import { ExclamationTriangleIcon } from '@patternfly/react-icons';
55
import { FormattedMessage } from 'react-intl';
66
import { translate as __ } from 'foremanReact/common/I18n';
7-
import { selectCVActivationKeys, selectCVHosts, selectCVVersions } from '../../../ContentViewDetailSelectors';
7+
import { selectCVVersions } from '../../../ContentViewDetailSelectors';
88
import DeleteContext from '../DeleteContext';
99
import WizardHeader from '../../../../components/WizardHeader';
10+
import AffectedHosts from '../affectedHosts';
11+
import AffectedActivationKeys from '../affectedActivationKeys';
1012

1113
const CVVersionRemoveReview = () => {
1214
const [alertDismissed, setAlertDismissed] = useState(false);
15+
const [showHosts, setShowHosts] = useState(false);
16+
const [showAKs, setShowAKs] = useState(false);
1317
const {
14-
cvId, versionIdToRemove, versionNameToRemove, selectedEnvSet,
18+
cvId, versionEnvironments, versionIdToRemove, versionNameToRemove, selectedEnvSet,
1519
selectedEnvForAK, selectedCVNameForAK, selectedCVNameForHosts,
16-
selectedEnvForHost, affectedActivationKeys, affectedHosts, deleteFlow, removeDeletionFlow,
20+
selectedEnvForHost, deleteFlow, removeDeletionFlow,
1721
} = useContext(DeleteContext);
18-
const activationKeysResponse = useSelector(state => selectCVActivationKeys(state, cvId));
19-
const hostsResponse = useSelector(state => selectCVHosts(state, cvId));
20-
const { results: hostResponse = [] } = hostsResponse || {};
21-
const { results: akResponse = [] } = activationKeysResponse || {};
2222
const cvVersions = useSelector(state => selectCVVersions(state, cvId));
2323
const versionDeleteInfo = __(`Version ${versionNameToRemove} will be deleted from all environments. It will no longer be available for promotion.`);
2424
const removalNotice = __(`Version ${versionNameToRemove} will be removed from the environments listed below, and will remain available for later promotion. ` +
@@ -29,16 +29,19 @@ const CVVersionRemoveReview = () => {
2929
.flatMap(cv => cv.content_view_environments || [])
3030
.filter(env => selectedEnvSet.has(env.environment_id));
3131

32-
const multiCVHosts = hostResponse?.filter(host =>
33-
host.content_facet_attributes?.multi_content_view_environment) || [];
34-
const multiCVHostsCount = multiCVHosts.length;
32+
const selectedEnvs = versionEnvironments.filter(env => selectedEnvSet.has(env.id));
3533

36-
const singleCVHostsCount = (hostResponse?.length || 0) - multiCVHostsCount;
34+
const hostCount = selectedEnvs.reduce((sum, env) =>
35+
sum + (env.host_count || 0), 0);
36+
const multiCVHostsCount = selectedEnvs.reduce((sum, env) =>
37+
sum + (env.multi_env_host_count || 0), 0);
38+
const singleCVHostsCount = hostCount - multiCVHostsCount;
3739

38-
const multiCVActivationKeys = akResponse.filter(key => key.multi_content_view_environment);
39-
const multiCVActivationKeysCount = multiCVActivationKeys.length;
40-
41-
const singleCVActivationKeysCount = akResponse.length - multiCVActivationKeysCount;
40+
const akCount = selectedEnvs.reduce((sum, env) =>
41+
sum + (env.activation_key_count || 0), 0);
42+
const multiCVActivationKeysCount = selectedEnvs.reduce((sum, env) =>
43+
sum + (env.multi_env_ak_count || 0), 0);
44+
const singleCVActivationKeysCount = akCount - multiCVActivationKeysCount;
4245

4346
return (
4447
<>
@@ -66,7 +69,7 @@ const CVVersionRemoveReview = () => {
6669
<FlexItem key={name}><Label color="purple" href={`/lifecycle_environments/${id}`}>{name}</Label></FlexItem>)}
6770
</Flex>
6871
</>}
69-
{affectedHosts &&
72+
{hostCount > 0 &&
7073
<>
7174
<h3>{__('Content hosts')}</h3>
7275
{singleCVHostsCount > 0 && (
@@ -121,8 +124,22 @@ const CVVersionRemoveReview = () => {
121124
</FlexItem>
122125
</Flex>
123126
)}
127+
<ExpandableSection
128+
toggleText={showHosts ? 'Hide hosts' : 'Show hosts'}
129+
onToggle={() => setShowHosts(prev => !prev)}
130+
isExpanded={showHosts}
131+
>
132+
<AffectedHosts
133+
{...{
134+
cvId,
135+
versionEnvironments,
136+
selectedEnvSet,
137+
}}
138+
deleteCV={false}
139+
/>
140+
</ExpandableSection>
124141
</>}
125-
{affectedActivationKeys &&
142+
{akCount > 0 &&
126143
<>
127144
<h3>{__('Activation keys')}</h3>
128145
{singleCVActivationKeysCount > 0 && (
@@ -177,6 +194,20 @@ const CVVersionRemoveReview = () => {
177194
</FlexItem>
178195
</Flex>
179196
)}
197+
<ExpandableSection
198+
toggleText={showAKs ? 'Hide activation keys' : 'Show activation keys'}
199+
onToggle={() => setShowAKs(prev => !prev)}
200+
isExpanded={showAKs}
201+
>
202+
<AffectedActivationKeys
203+
{...{
204+
cvId,
205+
versionEnvironments,
206+
selectedEnvSet,
207+
}}
208+
deleteCV={false}
209+
/>
210+
</ExpandableSection>
180211
</>}
181212
</>
182213
);

webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvVersionRemove.test.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import { renderWithRedux, patientlyWaitFor, fireEvent } from 'react-testing-lib-wrapper';
3-
import { nockInstance, assertNockRequest, mockAutocomplete, mockForemanAutocomplete } from '../../../../../../test-utils/nockWrapper';
3+
import { nockInstance, assertNockRequest, mockAutocomplete } from '../../../../../../test-utils/nockWrapper';
44
import api, { foremanApi } from '../../../../../../services/api';
55
import CONTENT_VIEWS_KEY from '../../../../ContentViewsConstants';
66
import ContentViewVersions from '../../ContentViewVersions';
@@ -123,7 +123,11 @@ test('Can open Remove wizard and remove version from simple environment', async
123123
test('Can open Remove wizard and remove version from environment with hosts', async (done) => {
124124
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
125125
const hostAutocompleteUrl = '/hosts/auto_complete_search';
126-
const hostAutocompleteScope = mockForemanAutocomplete(nockInstance, hostAutocompleteUrl);
126+
const hostAutocompleteScope = nockInstance
127+
.get(foremanApi.getApiUrl(hostAutocompleteUrl))
128+
.query(true)
129+
.times(2)
130+
.reply(200, []);
127131

128132
const scope = nockInstance
129133
.get(cvVersions)
@@ -138,6 +142,7 @@ test('Can open Remove wizard and remove version from environment with hosts', as
138142
const hostScope = nockInstance
139143
.get(hostURL)
140144
.query(true)
145+
.times(2)
141146
.reply(200, affectedHostData);
142147

143148
const cVDropDownOptionsScope = nockInstance
@@ -211,7 +216,11 @@ test('Can open Remove wizard and remove version from environment with hosts', as
211216
test('Can open Remove wizard and remove version from environment with activation keys', async (done) => {
212217
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
213218
const akAutocompleteUrl = '/activation_keys/auto_complete_search';
214-
const akAutocompleteScope = mockAutocomplete(nockInstance, akAutocompleteUrl);
219+
const akAutocompleteScope = nockInstance
220+
.get(api.getApiUrl(akAutocompleteUrl))
221+
.query(true)
222+
.times(2)
223+
.reply(200, []);
215224

216225
const scope = nockInstance
217226
.get(cvVersions)
@@ -226,6 +235,7 @@ test('Can open Remove wizard and remove version from environment with activation
226235
const activationKeysScope = nockInstance
227236
.get(activationKeyURL)
228237
.query(true)
238+
.times(2)
229239
.reply(200, affectedActivationKeysData);
230240

231241
const cVDropDownOptionsScope = nockInstance

0 commit comments

Comments
 (0)