diff --git a/app/lib/actions/katello/content_view_environment/reassign_objects.rb b/app/lib/actions/katello/content_view_environment/reassign_objects.rb index 74e0fedf4de..b479b939768 100644 --- a/app/lib/actions/katello/content_view_environment/reassign_objects.rb +++ b/app/lib/actions/katello/content_view_environment/reassign_objects.rb @@ -9,7 +9,11 @@ def plan(content_view_environment, options) end content_view_environment.activation_keys.each do |key| - plan_action(ActivationKey::Reassign, key, options[:key_content_view_id], options[:key_environment_id]) + if key.multi_content_view_environment? + key.content_view_environments = key.content_view_environments - [content_view_environment] + else + plan_action(ActivationKey::Reassign, key, options[:key_content_view_id], options[:key_environment_id]) + end end end end diff --git a/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js b/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js index cffab1454af..e273589571d 100644 --- a/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js +++ b/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js @@ -1,12 +1,13 @@ import React, { useState, useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import useDeepCompareEffect from 'use-deep-compare-effect'; -import { ExpandableSection, SelectOption } from '@patternfly/react-core'; +import { ExpandableSection, SelectOption, Alert, AlertActionCloseButton } from '@patternfly/react-core'; import { STATUS } from 'foremanReact/constants'; import { translate as __ } from 'foremanReact/common/I18n'; import EnvironmentPaths from '../../../../components/EnvironmentPaths/EnvironmentPaths'; import getContentViews from '../../../../ContentViewsActions'; import { selectContentViewError, selectContentViews, selectContentViewStatus } from '../../../../ContentViewSelectors'; +import { selectCVActivationKeys } from '../../../ContentViewDetailSelectors'; import AffectedActivationKeys from '../affectedActivationKeys'; import DeleteContext from '../DeleteContext'; import ContentViewSelect from '../../../../components/ContentViewSelect/ContentViewSelect'; @@ -17,7 +18,9 @@ const CVReassignActivationKeysForm = () => { const contentViewsInEnvResponse = useSelector(selectContentViews); const contentViewsInEnvStatus = useSelector(selectContentViewStatus); const contentViewsInEnvError = useSelector(selectContentViewError); + const activationKeysResponse = useSelector(selectCVActivationKeys); const cvInEnvLoading = contentViewsInEnvStatus === STATUS.PENDING; + const [alertDismissed, setAlertDismissed] = useState(false); const [cvSelectOpen, setCVSelectOpen] = useState(false); const [cvSelectOptions, setCvSelectionOptions] = useState([]); const [showActivationKeys, setShowActivationKeys] = useState(false); @@ -72,6 +75,9 @@ const CVReassignActivationKeysForm = () => { contentViewsInEnvError, selectedEnvForAK, setSelectedCVForAK, setSelectedCVNameForAK, cvInEnvLoading, selectedCVForAK, cvId, versionEnvironments, selectedEnvSet]); + const multiCVWarning = activationKeysResponse?.results?.some?.(key => + key.multi_content_view_environment); + const fetchSelectedCVName = (id) => { const { results } = contentViewsInEnvResponse ?? { }; return results.filter(cv => cv.id === id)[0]?.name; @@ -102,8 +108,21 @@ const CVReassignActivationKeysForm = () => { cvSelectOptions, }); + const multiCVRemovalInfo = __('This environment is used in one or more multi-environment activation keys. The environment will simply be removed from the multi-environment keys. The content view and lifecycle environment you select here will only apply to single-environment activation keys. See hammer activation-key --help for more details.'); + return ( <> + {!alertDismissed && multiCVWarning && ( + setAlertDismissed(true)} />} + > +

{multiCVRemovalInfo}

+
+ )} { const activationKeysResponse = useSelector(state => selectCVActivationKeys(state, cvId)); const hostsResponse = useSelector(state => selectCVHosts(state, cvId)); const { results: hostResponse } = hostsResponse; - const { results: akResponse } = activationKeysResponse; + const { results: akResponse = [] } = activationKeysResponse || {}; const selectedEnv = versionEnvironments.filter(env => selectedEnvSet.has(env.id)); const versionDeleteInfo = __(`Version ${versionNameToRemove} will be deleted from all environments. It will no longer be available for promotion.`); const removalNotice = __(`Version ${versionNameToRemove} will be removed from the environments listed below, and will remain available for later promotion. ` + 'Changes listed below will be effective after clicking Remove.'); + const multiCVActivationKeys = akResponse.filter(key => key.multi_content_view_environment); + const multiCVActivationKeysCount = multiCVActivationKeys.length; + + const singleCVActivationKeysCount = akResponse.length - multiCVActivationKeysCount; + return ( <> @@ -62,11 +67,23 @@ const CVVersionRemoveReview = () => { {affectedActivationKeys && <>

{__('Activation keys')}

- - -

{__(`${pluralize(akResponse.length, 'activation key')} will be moved to content view ${selectedCVNameForAK} in `)}

- -
+ {singleCVActivationKeysCount > 0 && ( + + +

{__(`${pluralize(singleCVActivationKeysCount, 'activation key')} will be moved to content view ${selectedCVNameForAK} in `)}

+ +
+ )} + {multiCVActivationKeysCount > 0 && ( + + + +

+ {__(`Content view environment will be removed from ${pluralize(multiCVActivationKeysCount, 'multi-environment activation key')}.`)} +

+
+
+ )} } ); diff --git a/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js b/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js index 02af9570e24..a08960f6e43 100644 --- a/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +++ b/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js @@ -35,6 +35,7 @@ const AffectedActivationKeys = ({ const columnHeaders = [ __('Name'), __('Environment'), + __('Multi Content View Environment'), ]; const emptyContentTitle = __('No matching activation keys found.'); const emptyContentBody = __("Given criteria doesn't match any activation keys. Try changing your rule."); @@ -65,12 +66,15 @@ const AffectedActivationKeys = ({ - {results?.map(({ name, id, environment }) => ( + {results?.map(({ + name, id, environment, multi_content_view_environment: multiContentViewEnvironment, + }) => ( {name} + { multiContentViewEnvironment ? 'Yes' : 'No' } )) }