Repository: kubevirt-ui/kubevirt-plugin
Pull request #2653: CNV-61181: Surface StorageProfile options
Author: login: rszwajko
Labels: name: lgtm
description: Passed code review, ready for merge
name: approved
description: This issue is something we want to fix
name: jira/valid-reference
Created: 2025-05-12T18:10:55Z | Merged: 2025-05-15T17:44:44Z

## 📝 Description


Follow-up to #2524

Make ApplyStorageProfileSettings component independent from
react-hook-form and re-use it for AddBootableVolumeModal and
CreateBootableVolumeModal. Both modals rely on useState hook to keep
the state.
To better encapsulate the functionality, the component will take over
the responsibility of clearing the volume/access modes after storage
class change. The storage class name is stored as ref to avoid using
setters as dependencies in the useEffect hook (component cannot assume
their references will be stable).


## 🎥 Demo
### Before
![image](https://github.com/user-attachments/assets/7b62cf5e-4bc4-46b9-8e75-7c6c71404cde)

![image](https://github.com/user-attachments/assets/a24c50f8-d155-40d1-aba0-96c275cbf635)

### After
![image](https://github.com/user-attachments/assets/a4ae0a4b-13dd-44c1-be0a-74966a27f1e3)


![Screenshot From 2025-05-12 20-04-44](https://github.com/user-attachments/assets/0598856e-df01-4c9a-9905-3920f0b614b1)



Diff:
diff --git a/locales/en/plugin__kubevirt-plugin.json b/locales/en/plugin__kubevirt-plugin.json
index c438fb1490..b7b48e2657 100644
--- a/locales/en/plugin__kubevirt-plugin.json
+++ b/locales/en/plugin__kubevirt-plugin.json
@@ -726,6 +726,7 @@
   "Learn how to create, import, and run virtual machines on OpenShift with step-by-step instructions and tasks.": "Learn how to create, import, and run virtual machines on OpenShift with step-by-step instructions and tasks.",
   "Learn how to use VirtualMachines": "Learn how to use VirtualMachines",
   "Learn more": "Learn more",
+  "Learn more about <2>StorageProfile</2>.": "Learn more about <2>StorageProfile</2>.",
   "Learn more about key areas to complete workflows, increase productivity, and familiarize yourself with Virtualization using our resources.": "Learn more about key areas to complete workflows, increase productivity, and familiarize yourself with Virtualization using our resources.",
   "Learn more about MigrationPolicies": "Learn more about MigrationPolicies",
   "Learn more about network latency checkups": "Learn more about network latency checkups",
@@ -736,7 +737,6 @@
   "Learn more about supported formats": "Learn more about supported formats",
   "Learn more about templates": "Learn more about templates",
   "Learn more about working with projects": "Learn more about working with projects",
-  "Learn more about<1> StorageProfile</1>.": "Learn more about<1> StorageProfile</1>.",
   "less than": "less than",
   "Less than": "Less than",
   "Limitations": "Limitations",
@@ -916,7 +916,6 @@
   "No network interfaces found": "No network interfaces found",
   "No network latency checkups found": "No network latency checkups found",
   "No NetworkAttachmentDefinitions available. Contact your system administrator for additional support.": "No NetworkAttachmentDefinitions available. Contact your system administrator for additional support.",
-  "No optimized StorageProfile settings for this StorageClass.": "No optimized StorageProfile settings for this StorageClass.",
   "No owner": "No owner",
   "No parameters found in this template.": "No parameters found in this template.",
   "No preferences found": "No preferences found",
@@ -985,7 +984,6 @@
   "Optimized for best performance. Supported by most Linux distributions. Windows requires additional drivers to use this model": "Optimized for best performance. Supported by most Linux distributions. Windows requires additional drivers to use this model",
   "Optimized for best performance. Supported by most Linux distributions. Windows requires additional drivers to use this model.": "Optimized for best performance. Supported by most Linux distributions. Windows requires additional drivers to use this model.",
   "Optimized for High resource consumption workloads": "Optimized for High resource consumption workloads",
-  "Optimized values Access mode: {{accessMode}}, Volume mode: {{volumeMode}}.": "Optimized values Access mode: {{accessMode}}, Volume mode: {{volumeMode}}.",
   "Optional parameters": "Optional parameters",
   "Organization ID": "Organization ID",
   "Other": "Other",
diff --git a/src/utils/components/AddBootableVolumeModal/AddBootableVolumeModal.tsx b/src/utils/components/AddBootableVolumeModal/AddBootableVolumeModal.tsx
index bc89d3cab5..e9d1388ea8 100644
--- a/src/utils/components/AddBootableVolumeModal/AddBootableVolumeModal.tsx
+++ b/src/utils/components/AddBootableVolumeModal/AddBootableVolumeModal.tsx
@@ -7,7 +7,6 @@ import TabModal from '@kubevirt-utils/components/TabModal/TabModal';
 import { useCDIUpload } from '@kubevirt-utils/hooks/useCDIUpload/useCDIUpload';
 import { UPLOAD_STATUS } from '@kubevirt-utils/hooks/useCDIUpload/utils';
 import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
-import useStorageProfileClaimPropertySets from '@kubevirt-utils/hooks/useStorageProfileClaimPropertySets';
 import { BootableVolume } from '@kubevirt-utils/resources/bootableresources/types';
 import { getValidNamespace, kubevirtConsole } from '@kubevirt-utils/utils/utils';
 import { useActiveNamespace } from '@openshift-console/dynamic-plugin-sdk';
@@ -59,14 +58,8 @@ const AddBootableVolumeModal: FC<AddBootableVolumeModalProps> = ({
     DROPDOWN_FORM_SELECTION.UPLOAD_VOLUME,
   );
 
-  const applyStorageProfileState = useState<boolean>(true);
-
   const { upload, uploadData } = useCDIUpload();
 
-  const claimPropertySetsData = useStorageProfileClaimPropertySets(
-    bootableVolume?.storageClassName,
-  );
-
   const { labels } = bootableVolume || {};
 
   const setBootableVolumeField: SetBootableVolumeFieldType = useCallback(
@@ -97,9 +90,7 @@ const AddBootableVolumeModal: FC<AddBootableVolumeModalProps> = ({
         onClose();
       }}
       onSubmit={createBootableVolume({
-        applyStorageProfileSettings: applyStorageProfileState[0],
         bootableVolume,
-        claimPropertySets: claimPropertySetsData?.claimPropertySets,
         onCreateVolume,
         sourceType,
         uploadData,
@@ -134,9 +125,7 @@ const AddBootableVolumeModal: FC<AddBootableVolumeModalProps> = ({
           {t('Destination details')}
         </Title>
         <VolumeDestination
-          applyStorageProfileState={applyStorageProfileState}
           bootableVolume={bootableVolume}
-          claimPropertySetsData={claimPropertySetsData}
           setBootableVolumeField={setBootableVolumeField}
         />
         <Title className="pf-v6-u-mt-md" headingLevel="h5">
diff --git a/src/utils/components/AddBootableVolumeModal/components/VolumeDestination/VolumeDestination.tsx b/src/utils/components/AddBootableVolumeModal/components/VolumeDestination/VolumeDestination.tsx
index cfcc80c017..c4a593895d 100644
--- a/src/utils/components/AddBootableVolumeModal/components/VolumeDestination/VolumeDestination.tsx
+++ b/src/utils/components/AddBootableVolumeModal/components/VolumeDestination/VolumeDestination.tsx
@@ -1,10 +1,9 @@
-import React, { Dispatch, FC, SetStateAction, useState } from 'react';
+import React, { FC, useState } from 'react';
 
-import ApplyStorageProfileSettingsCheckbox from '@kubevirt-utils/components/ApplyStorageProfileSettingsCheckbox/ApplyStorageProfileSettingsCheckbox';
+import ApplyStorageProfileSettings from '@kubevirt-utils/components/ApplyStorageProfileSettings/ApplyStorageProfileSettings';
 import CapacityInput from '@kubevirt-utils/components/CapacityInput/CapacityInput';
 import ProjectDropdown from '@kubevirt-utils/components/ProjectDropdown/ProjectDropdown';
 import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
-import { UseStorageProfileClaimPropertySetsValue } from '@kubevirt-utils/hooks/useStorageProfileClaimPropertySets';
 import { FormGroup, Grid, GridItem, TextInput } from '@patternfly/react-core';
 
 import { AddBootableVolumeState, SetBootableVolumeFieldType } from '../../utils/constants';
@@ -13,27 +12,25 @@ import DefaultStorageClassAlert from './StorageClass/DefaultStorageClassAlert';
 import StorageClassSelect from './StorageClass/StorageClassSelect';
 
 type VolumeDestinationProps = {
-  applyStorageProfileState: [boolean, Dispatch<SetStateAction<boolean>>];
   bootableVolume: AddBootableVolumeState;
-  claimPropertySetsData: UseStorageProfileClaimPropertySetsValue;
   setBootableVolumeField: SetBootableVolumeFieldType;
 };
 
 const VolumeDestination: FC<VolumeDestinationProps> = ({
-  applyStorageProfileState,
   bootableVolume,
-  claimPropertySetsData,
   setBootableVolumeField,
 }) => {
   const { t } = useKubevirtTranslation();
   const [showSCAlert, setShowSCAlert] = useState(false);
 
-  const { bootableVolumeName, bootableVolumeNamespace, size, storageClassName } =
-    bootableVolume || {};
-
-  const [applyStorageProfile, setApplyStorageProfile] = applyStorageProfileState;
-
-  const { claimPropertySets, loaded: storageProfileLoaded } = claimPropertySetsData;
+  const {
+    accessMode,
+    bootableVolumeName,
+    bootableVolumeNamespace,
+    size,
+    storageClassName,
+    volumeMode,
+  } = bootableVolume || {};
 
   return (
     <>
@@ -46,11 +43,10 @@ const VolumeDestination: FC<VolumeDestinationProps> = ({
           />
         </GridItem>
         <GridItem>
-          <ApplyStorageProfileSettingsCheckbox
-            claimPropertySets={claimPropertySets}
-            disabled={!storageProfileLoaded}
-            handleChange={setApplyStorageProfile}
-            isChecked={applyStorageProfile}
+          <ApplyStorageProfileSettings
+            {...{ accessMode, storageClassName, volumeMode }}
+            setAccessMode={setBootableVolumeField('accessMode')}
+            setVolumeMode={setBootableVolumeField('volumeMode')}
           />
         </GridItem>
         <GridItem span={6}>
diff --git a/src/utils/components/AddBootableVolumeModal/utils/constants.ts b/src/utils/components/AddBootableVolumeModal/utils/constants.ts
index 55657216f3..7d244deb71 100644
--- a/src/utils/components/AddBootableVolumeModal/utils/constants.ts
+++ b/src/utils/components/AddBootableVolumeModal/utils/constants.ts
@@ -6,6 +6,10 @@ import {
   V1beta1DataSource,
   V1beta1DataVolume,
 } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
+import {
+  V1beta1StorageSpecAccessModesEnum,
+  V1beta1StorageSpecVolumeModeEnum,
+} from '@kubevirt-ui/kubevirt-api/kubevirt';
 import { DEFAULT_DISK_SIZE } from '@kubevirt-utils/components/DiskModal/utils/constants';
 import { OPENSHIFT_OS_IMAGES_NS } from '@kubevirt-utils/constants/constants';
 import { CDI_BIND_REQUESTED_ANNOTATION } from '@kubevirt-utils/hooks/useCDIUpload/consts';
@@ -26,6 +30,7 @@ export const optionsValueLabelMapper = {
 };
 
 export type AddBootableVolumeState = {
+  accessMode?: V1beta1StorageSpecAccessModesEnum;
   annotations?: { [key: string]: string };
   bootableVolumeName: string;
   bootableVolumeNamespace: string;
@@ -43,6 +48,7 @@ export type AddBootableVolumeState = {
   storageClassProvisioner?: string;
   uploadFile?: File | string;
   uploadFilename?: string;
+  volumeMode?: V1beta1StorageSpecVolumeModeEnum;
 };
 
 export type SetBootableVolumeFieldType = (
diff --git a/src/utils/components/AddBootableVolumeModal/utils/utils.ts b/src/utils/components/AddBootableVolumeModal/utils/utils.ts
index c0d130d80a..09bcfa2f66 100644
--- a/src/utils/components/AddBootableVolumeModal/utils/utils.ts
+++ b/src/utils/components/AddBootableVolumeModal/utils/utils.ts
@@ -8,16 +8,12 @@ import {
   V1beta1DataImportCron,
   V1beta1DataSource,
 } from '@kubevirt-ui/kubevirt-api/containerized-data-importer/models';
-import {
-  V1beta1DataVolumeSource,
-  V1beta1StorageSpecVolumeModeEnum,
-} from '@kubevirt-ui/kubevirt-api/kubevirt';
+import { V1beta1DataVolumeSource } from '@kubevirt-ui/kubevirt-api/kubevirt';
 import { UploadDataProps } from '@kubevirt-utils/hooks/useCDIUpload/useCDIUpload';
 import { KUBEVIRT_ISO_LABEL } from '@kubevirt-utils/resources/bootableresources/constants';
 import { BootableVolume } from '@kubevirt-utils/resources/bootableresources/types';
 import { buildOwnerReference } from '@kubevirt-utils/resources/shared';
 import { DATA_SOURCE_CRONJOB_LABEL } from '@kubevirt-utils/resources/template';
-import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
 import { appendDockerPrefix, getRandomChars } from '@kubevirt-utils/utils/utils';
 import { k8sCreate, k8sDelete } from '@openshift-console/dynamic-plugin-sdk';
 
@@ -29,23 +25,14 @@ import {
 } from './constants';
 
 type createBootableVolumeType = (input: {
-  applyStorageProfileSettings: boolean;
   bootableVolume: AddBootableVolumeState;
-  claimPropertySets: ClaimPropertySets;
   onCreateVolume: (createdVolume: BootableVolume) => void;
   sourceType: DROPDOWN_FORM_SELECTION;
   uploadData: ({ dataVolume, file }: UploadDataProps) => Promise<void>;
 }) => (dataSource: V1beta1DataSource) => Promise<V1beta1DataSource>;
 
 export const createBootableVolume: createBootableVolumeType =
-  ({
-    applyStorageProfileSettings,
-    bootableVolume,
-    claimPropertySets,
-    onCreateVolume,
-    sourceType,
-    uploadData,
-  }) =>
+  ({ bootableVolume, onCreateVolume, sourceType, uploadData }) =>
   async (dataSource: V1beta1DataSource) => {
     const { bootableVolumeNamespace } = bootableVolume;
     const draftDataSource = setDataSourceMetadata(
@@ -59,19 +46,11 @@ export const createBootableVolume: createBootableVolumeType =
         createBootableVolumeFromUpload(
           bootableVolume,
           bootableVolumeNamespace,
-          applyStorageProfileSettings,
-          claimPropertySets,
           draftDataSource,
           uploadData,
         ),
       [DROPDOWN_FORM_SELECTION.USE_EXISTING_PVC]: () =>
-        createPVCBootableVolume(
-          bootableVolume,
-          bootableVolumeNamespace,
-          applyStorageProfileSettings,
-          claimPropertySets,
-          draftDataSource,
-        ),
+        createPVCBootableVolume(bootableVolume, bootableVolumeNamespace, draftDataSource),
       [DROPDOWN_FORM_SELECTION.USE_REGISTRY]: () =>
         createDataSourceWithImportCron(bootableVolume, draftDataSource),
       [DROPDOWN_FORM_SELECTION.USE_SNAPSHOT]: () =>
@@ -90,12 +69,11 @@ export const getInstanceTypeFromVolume = (bootableVolume: BootableVolume): strin
 
 const getDataVolumeWithSource = (
   bootableVolume: AddBootableVolumeState,
-  applyStorageProfileSettings: boolean,
-  claimPropertySets: ClaimPropertySets,
   namespace: string,
   dataVolumeSource: V1beta1DataVolumeSource,
 ) => {
-  const { bootableVolumeName, labels, size, storageClassName } = bootableVolume || {};
+  const { accessMode, bootableVolumeName, labels, size, storageClassName, volumeMode } =
+    bootableVolume || {};
 
   return produce(emptySourceDataVolume, (draftBootableVolume) => {
     draftBootableVolume.metadata.name = bootableVolumeName;
@@ -107,11 +85,8 @@ const getDataVolumeWithSource = (
       draftBootableVolume.spec.storage.storageClassName = storageClassName;
     }
 
-    if (!applyStorageProfileSettings) {
-      draftBootableVolume.spec.storage.accessModes = claimPropertySets?.[0]?.accessModes;
-      draftBootableVolume.spec.storage.volumeMode = claimPropertySets?.[0]
-        ?.volumeMode as V1beta1StorageSpecVolumeModeEnum;
-    }
+    draftBootableVolume.spec.storage.accessModes = accessMode ? [accessMode] : undefined;
+    draftBootableVolume.spec.storage.volumeMode = volumeMode;
 
     draftBootableVolume.spec.source = dataVolumeSource;
   });
@@ -140,20 +115,12 @@ const setDataSourceMetadata = (
 const createBootableVolumeFromUpload = async (
   bootableVolume: AddBootableVolumeState,
   namespace: string,
-  applyStorageProfileSettings: boolean,
-  claimPropertySets: ClaimPropertySets,
   draftDataSource: V1beta1DataSource,
   uploadData: ({ dataVolume, file }: UploadDataProps) => Promise<void>,
 ) => {
   const { isIso, uploadFile } = bootableVolume || {};
 
-  const bootableVolumeToCreate = getDataVolumeWithSource(
-    bootableVolume,
-    applyStorageProfileSettings,
-    claimPropertySets,
-    namespace,
-    { upload: {} },
-  );
+  const bootableVolumeToCreate = getDataVolumeWithSource(bootableVolume, namespace, { upload: {} });
 
   const dataSourceToCreate = produce(draftDataSource, (draftDS) => {
     if (isIso) {
@@ -196,19 +163,13 @@ const createSnapshotDataSource = async (
 export const createPVCBootableVolume = async (
   bootableVolume: AddBootableVolumeState,
   namespace: string,
-  applyStorageProfileSettings: boolean,
-  claimPropertySets: ClaimPropertySets,
   draftDataSource: V1beta1DataSource,
 ) => {
   const { pvcName, pvcNamespace } = bootableVolume || {};
 
-  const bootableVolumeToCreate = getDataVolumeWithSource(
-    bootableVolume,
-    applyStorageProfileSettings,
-    claimPropertySets,
-    namespace,
-    { pvc: { name: pvcName, namespace: pvcNamespace } },
-  );
+  const bootableVolumeToCreate = getDataVolumeWithSource(bootableVolume, namespace, {
+    pvc: { name: pvcName, namespace: pvcNamespace },
+  });
 
   const dataSourceToCreate = produce(draftDataSource, (draftDS) => {
     draftDS.spec.source = {
diff --git a/src/utils/components/DiskModal/components/StorageProfileSettings/AccessMode.tsx b/src/utils/components/ApplyStorageProfileSettings/AccessMode.tsx
similarity index 74%
rename from src/utils/components/DiskModal/components/StorageProfileSettings/AccessMode.tsx
rename to src/utils/components/ApplyStorageProfileSettings/AccessMode.tsx
index 9c9392da3d..a030ca5954 100644
--- a/src/utils/components/DiskModal/components/StorageProfileSettings/AccessMode.tsx
+++ b/src/utils/components/ApplyStorageProfileSettings/AccessMode.tsx
@@ -1,35 +1,37 @@
 import React, { FC } from 'react';
-import { useFormContext } from 'react-hook-form';
 import { Trans } from 'react-i18next';
 import { Link } from 'react-router-dom-v5-compat';
 
+import {
+  V1beta1StorageSpecAccessModesEnum,
+  V1beta1StorageSpecVolumeModeEnum,
+} from '@kubevirt-ui/kubevirt-api/kubevirt';
 import HelpTextIcon from '@kubevirt-utils/components/HelpTextIcon/HelpTextIcon';
 import { documentationURL } from '@kubevirt-utils/constants/documentation';
 import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
 import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
 import { FormGroup, Radio } from '@patternfly/react-core';
 
-import { V1DiskFormState } from '../../utils/types';
-import { ACCESS_MODE_FIELD, ACCESS_MODE_FIELDID, VOLUME_MODE_FIELD } from '../utils/constants';
-import { ACCESS_MODE_RADIO_OPTIONS, getAccessModesForVolume } from '../utils/modesMapping';
-
 import RecommendationLabel from './RecommendationLabel';
+import { ACCESS_MODE_RADIO_OPTIONS, getAccessModesForVolume } from './utils';
 
 import './ApplyStorageProfileSettings.scss';
 
 type AccessModeProps = {
+  accessMode: V1beta1StorageSpecAccessModesEnum;
   claimPropertySets: ClaimPropertySets;
+  setAccessMode: (accessMode: V1beta1StorageSpecAccessModesEnum) => void;
+  volumeMode: V1beta1StorageSpecVolumeModeEnum;
 };
 
-const AccessMode: FC<AccessModeProps> = ({ claimPropertySets }) => {
+export const AccessMode: FC<AccessModeProps> = ({
+  accessMode,
+  claimPropertySets,
+  setAccessMode,
+  volumeMode,
+}) => {
   const { t } = useKubevirtTranslation();
 
-  const { setValue, watch } = useFormContext<V1DiskFormState>();
-
-  const [accessModes, volumeMode] = watch([ACCESS_MODE_FIELD, VOLUME_MODE_FIELD]);
-
-  const accessMode = accessModes?.[0];
-
   const accessModesForVolume = getAccessModesForVolume(claimPropertySets, volumeMode);
 
   return (
@@ -38,9 +40,8 @@ const AccessMode: FC<AccessModeProps> = ({ claimPropertySets }) => {
         <HelpTextIcon
           bodyContent={
             <Trans ns="plugin__kubevirt-plugin" t={t}>
-              Learn more about
+              Learn more about{' '}
               <Link target="_blank" to={documentationURL.STORAGE_PROFILES}>
-                {' '}
                 StorageProfile
               </Link>
               .
@@ -48,7 +49,6 @@ const AccessMode: FC<AccessModeProps> = ({ claimPropertySets }) => {
           }
         />
       }
-      fieldId={ACCESS_MODE_FIELDID}
       isStack
       label={t('Access Mode')}
     >
@@ -65,13 +65,13 @@ const AccessMode: FC<AccessModeProps> = ({ claimPropertySets }) => {
           }
           onChange={(event, checked) => {
             if (checked) {
-              setValue(ACCESS_MODE_FIELD, [value]);
+              setAccessMode(value);
             }
           }}
           id={value}
           isChecked={value === accessMode}
           key={value}
-          name={ACCESS_MODE_FIELD}
+          name="accessMode"
         />
       ))}
     </FormGroup>
diff --git a/src/utils/components/DiskModal/components/StorageProfileSettings/ApplyStorageProfileSettings.scss b/src/utils/components/ApplyStorageProfileSettings/ApplyStorageProfileSettings.scss
similarity index 88%
rename from src/utils/components/DiskModal/components/StorageProfileSettings/ApplyStorageProfileSettings.scss
rename to src/utils/components/ApplyStorageProfileSettings/ApplyStorageProfileSettings.scss
index 1a20bdc4b6..fbd6669ff9 100644
--- a/src/utils/components/DiskModal/components/StorageProfileSettings/ApplyStorageProfileSettings.scss
+++ b/src/utils/components/ApplyStorageProfileSettings/ApplyStorageProfileSettings.scss
@@ -6,6 +6,6 @@
   &--labelWithGap {
     display: flex;
     gap: var(--pf-t--global--spacer--sm);
-    align-items: anchor-center;
+    align-items: center;
   }
 }
diff --git a/src/utils/components/ApplyStorageProfileSettings/ApplyStorageProfileSettings.tsx b/src/utils/components/ApplyStorageProfileSettings/ApplyStorageProfileSettings.tsx
new file mode 100644
index 0000000000..d6f3398f6a
--- /dev/null
+++ b/src/utils/components/ApplyStorageProfileSettings/ApplyStorageProfileSettings.tsx
@@ -0,0 +1,74 @@
+import React, { FC, useEffect, useRef } from 'react';
+
+import {
+  V1beta1StorageSpecAccessModesEnum,
+  V1beta1StorageSpecVolumeModeEnum,
+} from '@kubevirt-ui/kubevirt-api/kubevirt';
+import ErrorAlert from '@kubevirt-utils/components/ErrorAlert/ErrorAlert';
+import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
+import useStorageProfileClaimPropertySets from '@kubevirt-utils/hooks/useStorageProfileClaimPropertySets';
+import { Flex, FlexItem, Skeleton } from '@patternfly/react-core';
+
+import AccessMode from './AccessMode';
+import VolumeMode from './VolumeMode';
+
+import './ApplyStorageProfileSettings.scss';
+
+type ApplyStorageProfileSettingsProps = {
+  accessMode: V1beta1StorageSpecAccessModesEnum;
+  setAccessMode: (accessMode?: V1beta1StorageSpecAccessModesEnum) => void;
+  setVolumeMode: (volumeMode?: V1beta1StorageSpecVolumeModeEnum) => void;
+  storageClassName: string;
+  volumeMode: V1beta1StorageSpecVolumeModeEnum;
+};
+
+const ApplyStorageProfileSettings: FC<ApplyStorageProfileSettingsProps> = ({
+  accessMode,
+  setAccessMode,
+  setVolumeMode,
+  storageClassName,
+  volumeMode,
+}) => {
+  const { t } = useKubevirtTranslation();
+  const { claimPropertySets, error, loaded } = useStorageProfileClaimPropertySets(storageClassName);
+  const storageRef = useRef<string>(undefined);
+
+  useEffect(() => {
+    if (storageRef.current === storageClassName) {
+      return;
+    }
+    storageRef.current = storageClassName;
+    setAccessMode(undefined);
+    setVolumeMode(undefined);
+  });
+
+  if (!loaded) {
+    return <Skeleton screenreaderText={t('Loading StorageProfile')} />;
+  }
+
+  if (loaded && error) {
+    return <ErrorAlert error={error} />;
+  }
+
+  return (
+    <Flex
+      className="ApplyStorageProfileSettings--volume-access-section"
+      spaceItems={{ default: 'spaceItems3xl' }}
+    >
+      <FlexItem>
+        <VolumeMode
+          claimPropertySets={claimPropertySets ?? []}
+          {...{ setAccessMode, setVolumeMode, volumeMode }}
+        />
+      </FlexItem>
+      <FlexItem>
+        <AccessMode
+          claimPropertySets={claimPropertySets ?? []}
+          {...{ accessMode, setAccessMode, volumeMode }}
+        />
+      </FlexItem>
+    </Flex>
+  );
+};
+
+export default ApplyStorageProfileSettings;
diff --git a/src/utils/components/DiskModal/components/StorageProfileSettings/RecommendationLabel.tsx b/src/utils/components/ApplyStorageProfileSettings/RecommendationLabel.tsx
similarity index 100%
rename from src/utils/components/DiskModal/components/StorageProfileSettings/RecommendationLabel.tsx
rename to src/utils/components/ApplyStorageProfileSettings/RecommendationLabel.tsx
diff --git a/src/utils/components/DiskModal/components/StorageProfileSettings/VolumeMode.tsx b/src/utils/components/ApplyStorageProfileSettings/VolumeMode.tsx
similarity index 74%
rename from src/utils/components/DiskModal/components/StorageProfileSettings/VolumeMode.tsx
rename to src/utils/components/ApplyStorageProfileSettings/VolumeMode.tsx
index cc170f8f58..cde76abb26 100644
--- a/src/utils/components/DiskModal/components/StorageProfileSettings/VolumeMode.tsx
+++ b/src/utils/components/ApplyStorageProfileSettings/VolumeMode.tsx
@@ -1,33 +1,39 @@
 import React, { FC, useCallback, useEffect } from 'react';
-import { useFormContext } from 'react-hook-form';
 import { Trans } from 'react-i18next';
 import { Link } from 'react-router-dom-v5-compat';
 import { uniq } from 'lodash';
 
-import { V1beta1StorageSpecVolumeModeEnum } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import HelpTextIcon from '@kubevirt-utils/components/HelpTextIcon/HelpTextIcon';
+import {
+  V1beta1StorageSpecAccessModesEnum,
+  V1beta1StorageSpecVolumeModeEnum,
+} from '@kubevirt-ui/kubevirt-api/kubevirt';
 import { documentationURL } from '@kubevirt-utils/constants/documentation';
 import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
 import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
 import { FormGroup, Radio } from '@patternfly/react-core';
 
-import { V1DiskFormState } from '../../utils/types';
-import { ACCESS_MODE_FIELD, VOLUME_MODE_FIELD, VOLUMEMODE_FIELDID } from '../utils/constants';
-import { getAccessModesForVolume, VOLUME_MODE_RADIO_OPTIONS } from '../utils/modesMapping';
+import HelpTextIcon from '../HelpTextIcon/HelpTextIcon';
 
 import RecommendationLabel from './RecommendationLabel';
+import { getAccessModesForVolume, VOLUME_MODE_RADIO_OPTIONS } from './utils';
 
 import './ApplyStorageProfileSettings.scss';
+
 type VolumeModeProps = {
   claimPropertySets: ClaimPropertySets;
+  setAccessMode: (accessMode?: V1beta1StorageSpecAccessModesEnum) => void;
+  setVolumeMode: (volumeMode?: V1beta1StorageSpecVolumeModeEnum) => void;
+  volumeMode: V1beta1StorageSpecVolumeModeEnum;
 };
 
-const VolumeMode: FC<VolumeModeProps> = ({ claimPropertySets }) => {
+export const VolumeMode: FC<VolumeModeProps> = ({
+  claimPropertySets,
+  setAccessMode,
+  setVolumeMode,
+  volumeMode,
+}) => {
   const { t } = useKubevirtTranslation();
 
-  const { setValue, watch } = useFormContext<V1DiskFormState>();
-
-  const volumeMode = watch(VOLUME_MODE_FIELD);
   const recommendedVolumeModes = uniq(
     claimPropertySets
       .map((it) => it.volumeMode)
@@ -39,10 +45,10 @@ const VolumeMode: FC<VolumeModeProps> = ({ claimPropertySets }) => {
   const setBothModes = useCallback(
     (mode) => {
       const accessModes = getAccessModesForVolume(claimPropertySets, mode);
-      setValue(VOLUME_MODE_FIELD, mode);
-      setValue(ACCESS_MODE_FIELD, accessModes.length > 0 ? [accessModes[0]] : undefined);
+      setAccessMode(accessModes[0]);
+      setVolumeMode(mode);
     },
-    [claimPropertySets, setValue],
+    [claimPropertySets, setAccessMode, setVolumeMode],
   );
 
   useEffect(() => {
@@ -59,9 +65,8 @@ const VolumeMode: FC<VolumeModeProps> = ({ claimPropertySets }) => {
         <HelpTextIcon
           bodyContent={
             <Trans ns="plugin__kubevirt-plugin" t={t}>
-              Learn more about
+              Learn more about{' '}
               <Link target="_blank" to={documentationURL.STORAGE_PROFILES}>
-                {' '}
                 StorageProfile
               </Link>
               .
@@ -69,7 +74,6 @@ const VolumeMode: FC<VolumeModeProps> = ({ claimPropertySets }) => {
           }
         />
       }
-      fieldId={VOLUMEMODE_FIELDID}
       isStack
       label={t('Volume Mode')}
     >
@@ -92,7 +96,7 @@ const VolumeMode: FC<VolumeModeProps> = ({ claimPropertySets }) => {
           id={value}
           isChecked={value === volumeMode}
           key={value}
-          name={VOLUME_MODE_FIELD}
+          name="volumeMode"
         />
       ))}
     </FormGroup>
diff --git a/src/utils/components/ApplyStorageProfileSettings/utils.ts b/src/utils/components/ApplyStorageProfileSettings/utils.ts
new file mode 100644
index 0000000000..65aa338c48
--- /dev/null
+++ b/src/utils/components/ApplyStorageProfileSettings/utils.ts
@@ -0,0 +1,89 @@
+/* eslint-disable @typescript-eslint/no-shadow */
+import { TFunction } from 'react-i18next';
+import { uniq } from 'lodash';
+
+import {
+  V1beta1StorageSpecAccessModesEnum,
+  V1beta1StorageSpecVolumeModeEnum,
+} from '@kubevirt-ui/kubevirt-api/kubevirt';
+import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation';
+import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
+
+export const tooltipForOtherRecommended = (priority: number, t: TFunction): string => {
+  switch (priority) {
+    case 1:
+      return t('The 2nd most suggested option in StorageProfile.');
+    case 2:
+      return t('The 3rd most suggested option in StorageProfile.');
+    default:
+      return t('The {{priority}}th most suggested option in StorageProfile.', {
+        priority: priority + 1,
+      });
+  }
+};
+
+export const fromPriorityToLabels = (
+  priority: number,
+  recommendationCount: number,
+  t: TFunction,
+): { className?: string; label: string; tooltip: string } => {
+  if (priority === 0) {
+    return {
+      className: 'pf-m-success',
+      label: t('Highly recommended'),
+      tooltip: t('The most suggested StorageProfile option.'),
+    };
+  }
+
+  if (priority > 0 && priority < recommendationCount) {
+    return {
+      label: t('Recommended'),
+      tooltip: tooltipForOtherRecommended(priority, t),
+    };
+  }
+
+  return {
+    className: 'pf-m-warning',
+    label: t('Not recommended'),
+    tooltip: t('We suggest using another option.'),
+  };
+};
+
+export const ACCESS_MODE_RADIO_OPTIONS = [
+  {
+    label: t('Single user (RWO)'),
+    value: V1beta1StorageSpecAccessModesEnum.ReadWriteOnce,
+  },
+  {
+    label: t('Shared access (RWX)'),
+    value: V1beta1StorageSpecAccessModesEnum.ReadWriteMany,
+  },
+  {
+    label: t('Read only (ROX)'),
+    value: V1beta1StorageSpecAccessModesEnum.ReadOnlyMany,
+  },
+];
+
+export const VOLUME_MODE_RADIO_OPTIONS = [
+  {
+    label: t('Filesystem'),
+    value: V1beta1StorageSpecVolumeModeEnum.Filesystem,
+  },
+  {
+    label: t('Block'),
+    value: V1beta1StorageSpecVolumeModeEnum.Block,
+  },
+];
+
+export const getAccessModesForVolume = (
+  claimPropertySets: ClaimPropertySets,
+  volumeMode?: string,
+) =>
+  uniq(
+    claimPropertySets
+      .filter((it) => it.volumeMode === volumeMode)
+      .flatMap((it) => it.accessModes)
+      .filter(Boolean)
+      .map((mode) => V1beta1StorageSpecAccessModesEnum[mode])
+      .filter(Boolean),
+  );
diff --git a/src/utils/components/ApplyStorageProfileSettingsCheckbox/ApplyStorageProfileSettingsCheckbox.tsx b/src/utils/components/ApplyStorageProfileSettingsCheckbox/ApplyStorageProfileSettingsCheckbox.tsx
deleted file mode 100644
index ab27d3355d..0000000000
--- a/src/utils/components/ApplyStorageProfileSettingsCheckbox/ApplyStorageProfileSettingsCheckbox.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import React, { FC } from 'react';
-
-import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
-import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
-import { isEmpty } from '@kubevirt-utils/utils/utils';
-import { Checkbox, FormGroup } from '@patternfly/react-core';
-
-import FormGroupHelperText from '../FormGroupHelperText/FormGroupHelperText';
-
-type ApplyStorageProfileSettingsCheckboxProps = {
-  claimPropertySets: ClaimPropertySets;
-  disabled?: boolean;
-  handleChange: (checked: boolean) => void;
-  isChecked: boolean;
-};
-
-const ApplyStorageProfileSettingsCheckbox: FC<ApplyStorageProfileSettingsCheckboxProps> = ({
-  claimPropertySets,
-  disabled,
-  handleChange,
-  isChecked,
-}) => {
-  const { t } = useKubevirtTranslation();
-
-  return (
-    <FormGroup fieldId="apply-storage-profile-settings" isInline>
-      <Checkbox
-        id="apply-storage-profile-settings"
-        isChecked={isChecked}
-        isDisabled={disabled}
-        label={t('Apply optimized StorageProfile settings')}
-        onChange={(_, checked: boolean) => handleChange(checked)}
-      />
-      <FormGroupHelperText>
-        {isEmpty(claimPropertySets)
-          ? t('No optimized StorageProfile settings for this StorageClass.')
-          : t('Optimized values Access mode: {{accessMode}}, Volume mode: {{volumeMode}}.', {
-              accessMode: claimPropertySets?.[0]?.accessModes[0],
-              volumeMode: claimPropertySets?.[0]?.volumeMode,
-            })}
-      </FormGroupHelperText>
-    </FormGroup>
-  );
-};
-
-export default ApplyStorageProfileSettingsCheckbox;
diff --git a/src/utils/components/DiskModal/components/StorageClassAndPreallocation/StorageClassSelect.tsx b/src/utils/components/DiskModal/components/StorageClassAndPreallocation/StorageClassSelect.tsx
index c6a1d0aa45..9d0e9a90b5 100644
--- a/src/utils/components/DiskModal/components/StorageClassAndPreallocation/StorageClassSelect.tsx
+++ b/src/utils/components/DiskModal/components/StorageClassAndPreallocation/StorageClassSelect.tsx
@@ -12,12 +12,10 @@ import { FormGroup } from '@patternfly/react-core';
 
 import { V1DiskFormState } from '../../utils/types';
 import {
-  ACCESS_MODE_FIELD,
   STORAGE_CLASS_FIELD,
   STORAGE_CLASS_PROVIDER_FIELD,
   STORAGE_SOURCE_BLANK,
   STORAGECLASS_SELECT_FIELDID,
-  VOLUME_MODE_FIELD,
 } from '../utils/constants';
 
 import { getSCSelectOptions } from './utils/helpers';
@@ -49,8 +47,6 @@ const StorageClassSelect: FC<StorageClassSelectProps> = ({ checkSC, setShowSCAle
       setValue(STORAGE_CLASS_FIELD, selection);
 
       setValue(STORAGE_CLASS_PROVIDER_FIELD, scMapper[selection]?.provisioner);
-      setValue(VOLUME_MODE_FIELD, undefined);
-      setValue(ACCESS_MODE_FIELD, undefined);
     },
     [scMapper, setValue, checkAndShowAlerts],
   );
diff --git a/src/utils/components/DiskModal/components/StorageProfileSettings/ApplyStorageProfileSettings.tsx b/src/utils/components/DiskModal/components/StorageProfileSettings/ApplyStorageProfileSettings.tsx
index 55bc7eb257..7037b770fd 100644
--- a/src/utils/components/DiskModal/components/StorageProfileSettings/ApplyStorageProfileSettings.tsx
+++ b/src/utils/components/DiskModal/components/StorageProfileSettings/ApplyStorageProfileSettings.tsx
@@ -1,49 +1,34 @@
 import React, { FC } from 'react';
 import { useFormContext } from 'react-hook-form';
 
-import ErrorAlert from '@kubevirt-utils/components/ErrorAlert/ErrorAlert';
-import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
-import useStorageProfileClaimPropertySets from '@kubevirt-utils/hooks/useStorageProfileClaimPropertySets';
-import { Flex, FlexItem, Skeleton } from '@patternfly/react-core';
+import ApplyStorageProfileSettings from '@kubevirt-utils/components/ApplyStorageProfileSettings/ApplyStorageProfileSettings';
 
 import { V1DiskFormState } from '../../utils/types';
-import { DATAVOLUME_TEMPLATE_STORAGE } from '../utils/constants';
-
-import AccessMode from './AccessMode';
-import VolumeMode from './VolumeMode';
-
-import './ApplyStorageProfileSettings.scss';
-
-const ApplyStorageProfileSettings: FC = () => {
-  const { t } = useKubevirtTranslation();
-  const { watch } = useFormContext<V1DiskFormState>();
-
-  const [storage] = watch([DATAVOLUME_TEMPLATE_STORAGE]);
+import {
+  ACCESS_MODE_FIELD,
+  DATAVOLUME_TEMPLATE_STORAGE,
+  VOLUME_MODE_FIELD,
+} from '../utils/constants';
+
+const ApplyStorageProfileSettingsToDisk: FC = () => {
+  const { setValue, watch } = useFormContext<V1DiskFormState>();
+
+  const [storage, accessModes, volumeMode] = watch([
+    DATAVOLUME_TEMPLATE_STORAGE,
+    ACCESS_MODE_FIELD,
+    VOLUME_MODE_FIELD,
+  ]);
   const { storageClassName = '' } = storage ?? {};
 
-  const { claimPropertySets, error, loaded } = useStorageProfileClaimPropertySets(storageClassName);
-
-  if (!loaded) {
-    return <Skeleton screenreaderText={t('Loading StorageProfile')} />;
-  }
-
-  if (loaded && error) {
-    return <ErrorAlert error={error} />;
-  }
+  const accessMode = accessModes?.[0];
 
   return (
-    <Flex
-      className="ApplyStorageProfileSettings--volume-access-section"
-      spaceItems={{ default: 'spaceItems3xl' }}
-    >
-      <FlexItem>
-        <VolumeMode claimPropertySets={claimPropertySets ?? []} />
-      </FlexItem>
-      <FlexItem>
-        <AccessMode claimPropertySets={claimPropertySets ?? []} />
-      </FlexItem>
-    </Flex>
+    <ApplyStorageProfileSettings
+      {...{ accessMode, storageClassName, volumeMode }}
+      setAccessMode={(value) => setValue(ACCESS_MODE_FIELD, value ? [value] : undefined)}
+      setVolumeMode={(value) => setValue(VOLUME_MODE_FIELD, value)}
+    />
   );
 };
 
-export default ApplyStorageProfileSettings;
+export default ApplyStorageProfileSettingsToDisk;
diff --git a/src/utils/components/DiskModal/components/StorageProfileSettings/utils.ts b/src/utils/components/DiskModal/components/StorageProfileSettings/utils.ts
deleted file mode 100644
index 7a26d15849..0000000000
--- a/src/utils/components/DiskModal/components/StorageProfileSettings/utils.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { TFunction } from 'react-i18next';
-
-export const tooltipForOtherRecommended = (priority: number, t: TFunction): string => {
-  switch (priority) {
-    case 1:
-      return t('The 2nd most suggested option in StorageProfile.');
-    case 2:
-      return t('The 3rd most suggested option in StorageProfile.');
-    default:
-      return t('The {{priority}}th most suggested option in StorageProfile.', {
-        priority: priority + 1,
-      });
-  }
-};
-
-export const fromPriorityToLabels = (
-  priority: number,
-  recommendationCount: number,
-  t: TFunction,
-): { className?: string; label: string; tooltip: string } => {
-  if (priority === 0) {
-    return {
-      className: 'pf-m-success',
-      label: t('Highly recommended'),
-      tooltip: t('The most suggested StorageProfile option.'),
-    };
-  }
-
-  if (priority > 0 && priority < recommendationCount) {
-    return {
-      label: t('Recommended'),
-      tooltip: tooltipForOtherRecommended(priority, t),
-    };
-  }
-
-  return {
-    className: 'pf-m-warning',
-    label: t('Not recommended'),
-    tooltip: t('We suggest using another option.'),
-  };
-};
diff --git a/src/utils/components/DiskModal/components/utils/modesMapping.ts b/src/utils/components/DiskModal/components/utils/modesMapping.ts
index 416130da0a..80b674fa57 100644
--- a/src/utils/components/DiskModal/components/utils/modesMapping.ts
+++ b/src/utils/components/DiskModal/components/utils/modesMapping.ts
@@ -1,11 +1,7 @@
-import { uniq } from 'lodash';
-
 import {
   V1beta1StorageSpecAccessModesEnum,
   V1beta1StorageSpecVolumeModeEnum,
 } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation';
-import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
 
 export const initialAccessModes: V1beta1StorageSpecAccessModesEnum[] = [
   V1beta1StorageSpecAccessModesEnum.ReadWriteMany,
@@ -200,32 +196,6 @@ export const provisionerAccessModeMapping: ProvisionerAccessModeMapping = {
   },
 };
 
-export const ACCESS_MODE_RADIO_OPTIONS = [
-  {
-    label: t('Single user (RWO)'),
-    value: V1beta1StorageSpecAccessModesEnum.ReadWriteOnce,
-  },
-  {
-    label: t('Shared access (RWX)'),
-    value: V1beta1StorageSpecAccessModesEnum.ReadWriteMany,
-  },
-  {
-    label: t('Read only (ROX)'),
-    value: V1beta1StorageSpecAccessModesEnum.ReadOnlyMany,
-  },
-];
-
-export const VOLUME_MODE_RADIO_OPTIONS = [
-  {
-    label: t('Filesystem'),
-    value: V1beta1StorageSpecVolumeModeEnum.Filesystem,
-  },
-  {
-    label: t('Block'),
-    value: V1beta1StorageSpecVolumeModeEnum.Block,
-  },
-];
-
 export const getAccessModeForProvisioner = (
   provisioner: string,
   volumeMode: V1beta1StorageSpecVolumeModeEnum,
@@ -255,16 +225,3 @@ export const getVolumeModeForProvisioner = (
 
   return initialVolumeModes;
 };
-
-export const getAccessModesForVolume = (
-  claimPropertySets: ClaimPropertySets,
-  volumeMode?: string,
-) =>
-  uniq(
-    claimPropertySets
-      .filter((it) => it.volumeMode === volumeMode)
-      .flatMap((it) => it.accessModes)
-      .filter(Boolean)
-      .map((mode) => V1beta1StorageSpecAccessModesEnum[mode])
-      .filter(Boolean),
-  );
diff --git a/src/views/cdi-upload-provider/upload-pvc-form/UploadPVCFormAccessMode.tsx b/src/views/cdi-upload-provider/upload-pvc-form/UploadPVCFormAccessMode.tsx
index d0a101f911..1eefcdbd97 100644
--- a/src/views/cdi-upload-provider/upload-pvc-form/UploadPVCFormAccessMode.tsx
+++ b/src/views/cdi-upload-provider/upload-pvc-form/UploadPVCFormAccessMode.tsx
@@ -1,9 +1,7 @@
 import React, { FC, useCallback, useEffect, useState } from 'react';
 
-import {
-  ACCESS_MODE_RADIO_OPTIONS,
-  getAccessModeForProvisioner,
-} from '@kubevirt-utils/components/DiskModal/components/utils/modesMapping';
+import { ACCESS_MODE_RADIO_OPTIONS } from '@kubevirt-utils/components/ApplyStorageProfileSettings/utils';
+import { getAccessModeForProvisioner } from '@kubevirt-utils/components/DiskModal/components/utils/modesMapping';
 import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
 import { FormGroup, Radio } from '@patternfly/react-core';
 
diff --git a/src/views/cdi-upload-provider/upload-pvc-form/UploadPVCFormVolumeMode.tsx b/src/views/cdi-upload-provider/upload-pvc-form/UploadPVCFormVolumeMode.tsx
index 29c16e7083..1284400e79 100644
--- a/src/views/cdi-upload-provider/upload-pvc-form/UploadPVCFormVolumeMode.tsx
+++ b/src/views/cdi-upload-provider/upload-pvc-form/UploadPVCFormVolumeMode.tsx
@@ -2,10 +2,8 @@ import React, { FC, useMemo } from 'react';
 import { Trans } from 'react-i18next';
 
 import { V1beta1StorageSpecAccessModesEnum } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import {
-  getVolumeModeForProvisioner,
-  VOLUME_MODE_RADIO_OPTIONS,
-} from '@kubevirt-utils/components/DiskModal/components/utils/modesMapping';
+import { VOLUME_MODE_RADIO_OPTIONS } from '@kubevirt-utils/components/ApplyStorageProfileSettings/utils';
+import { getVolumeModeForProvisioner } from '@kubevirt-utils/components/DiskModal/components/utils/modesMapping';
 import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
 import { FormGroup, Radio } from '@patternfly/react-core';
 
diff --git a/src/views/virtualmachines/details/tabs/configuration/storage/components/modal/CreateBootableVolumeModal.tsx b/src/views/virtualmachines/details/tabs/configuration/storage/components/modal/CreateBootableVolumeModal.tsx
index efc04ae023..935283d34c 100644
--- a/src/views/virtualmachines/details/tabs/configuration/storage/components/modal/CreateBootableVolumeModal.tsx
+++ b/src/views/virtualmachines/details/tabs/configuration/storage/components/modal/CreateBootableVolumeModal.tsx
@@ -21,7 +21,6 @@ import { removeByteSuffix } from '@kubevirt-utils/components/CapacityInput/utils
 import HelpTextIcon from '@kubevirt-utils/components/HelpTextIcon/HelpTextIcon';
 import TabModal from '@kubevirt-utils/components/TabModal/TabModal';
 import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
-import useStorageProfileClaimPropertySets from '@kubevirt-utils/hooks/useStorageProfileClaimPropertySets';
 import { modelToGroupVersionKind, PersistentVolumeClaimModel } from '@kubevirt-utils/models';
 import { getName, getNamespace, getResourceUrl } from '@kubevirt-utils/resources/shared';
 import { getInstanceTypeMatcher, getPreferenceMatcher } from '@kubevirt-utils/resources/vm';
@@ -29,7 +28,7 @@ import { NO_DATA_DASH } from '@kubevirt-utils/resources/vm/utils/constants';
 import { DiskRowDataLayout } from '@kubevirt-utils/resources/vm/utils/disk/constants';
 import { hasSizeUnit } from '@kubevirt-utils/resources/vm/utils/disk/size';
 import { useK8sWatchResource } from '@openshift-console/dynamic-plugin-sdk';
-import { PopoverPosition, Stack, Title } from '@patternfly/react-core';
+import { Form, PopoverPosition, Stack, Title } from '@patternfly/react-core';
 
 import { createBootableVolumeFromDisk } from './utils';
 
@@ -67,11 +66,6 @@ const CreateBootableVolumeModal: FC<CreateBootableVolumeModalProps> = ({
     pvcNamespace: diskObj?.namespace,
     storageClassName: diskObj?.storageClass === NO_DATA_DASH ? null : diskObj?.storageClass,
   });
-  const applyStorageProfileState = useState<boolean>(true);
-
-  const claimPropertySetsData = useStorageProfileClaimPropertySets(
-    bootableVolume?.storageClassName,
-  );
 
   const setBootableVolumeField: SetBootableVolumeFieldType = useCallback(
     (key, fieldKey) => (value) =>
@@ -94,13 +88,7 @@ const CreateBootableVolumeModal: FC<CreateBootableVolumeModalProps> = ({
   };
 
   const onSubmit = async () => {
-    const createdDS = await createBootableVolumeFromDisk(
-      diskObj,
-      vm,
-      bootableVolume,
-      applyStorageProfileState[0],
-      claimPropertySetsData.claimPropertySets,
-    );
+    const createdDS = await createBootableVolumeFromDisk(diskObj, vm, bootableVolume);
 
     navigate(getResourceUrl({ model: DataSourceModel, resource: createdDS }));
   };
@@ -126,30 +114,30 @@ const CreateBootableVolumeModal: FC<CreateBootableVolumeModalProps> = ({
       onSubmit={onSubmit}
       submitBtnText={t('Save')}
     >
-      <Stack hasGutter>
-        <Title className="pf-v6-u-mt-md" headingLevel="h5">
-          {t('Destination details')}
-        </Title>
-        <VolumeDestination
-          applyStorageProfileState={applyStorageProfileState}
-          bootableVolume={bootableVolume}
-          claimPropertySetsData={claimPropertySetsData}
-          setBootableVolumeField={setBootableVolumeField}
-        />
-        <Title className="pf-v6-u-mt-md" headingLevel="h5">
-          {t('Volume metadata')}{' '}
-          <HelpTextIcon
-            bodyContent={t('Set the volume metadata to use the volume as a bootable image.')}
-            helpIconClassName="add-bootable-volume-modal__title-help-text-icon"
-            position={PopoverPosition.right}
+      <Form>
+        <Stack hasGutter>
+          <Title className="pf-v6-u-mt-md" headingLevel="h5">
+            {t('Destination details')}
+          </Title>
+          <VolumeDestination
+            bootableVolume={bootableVolume}
+            setBootableVolumeField={setBootableVolumeField}
+          />
+          <Title className="pf-v6-u-mt-md" headingLevel="h5">
+            {t('Volume metadata')}{' '}
+            <HelpTextIcon
+              bodyContent={t('Set the volume metadata to use the volume as a bootable image.')}
+              helpIconClassName="add-bootable-volume-modal__title-help-text-icon"
+              position={PopoverPosition.right}
+            />
+          </Title>
+          <VolumeMetadata
+            bootableVolume={bootableVolume}
+            deleteLabel={deleteLabel}
+            setBootableVolumeField={setBootableVolumeField}
           />
-        </Title>
-        <VolumeMetadata
-          bootableVolume={bootableVolume}
-          deleteLabel={deleteLabel}
-          setBootableVolumeField={setBootableVolumeField}
-        />
-      </Stack>
+        </Stack>
+      </Form>
     </TabModal>
   );
 };
diff --git a/src/views/virtualmachines/details/tabs/configuration/storage/components/modal/utils.ts b/src/views/virtualmachines/details/tabs/configuration/storage/components/modal/utils.ts
index 744536bfd1..c240e1282a 100644
--- a/src/views/virtualmachines/details/tabs/configuration/storage/components/modal/utils.ts
+++ b/src/views/virtualmachines/details/tabs/configuration/storage/components/modal/utils.ts
@@ -25,7 +25,6 @@ import {
 } from '@kubevirt-utils/resources/vm';
 import { DiskRowDataLayout } from '@kubevirt-utils/resources/vm/utils/disk/constants';
 import { getVMIDevices } from '@kubevirt-utils/resources/vmi';
-import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
 import { ensurePath, isEmpty } from '@kubevirt-utils/utils/utils';
 import { k8sGet } from '@openshift-console/dynamic-plugin-sdk';
 
@@ -33,8 +32,6 @@ export const createBootableVolumeFromDisk = async (
   diskObj: DiskRowDataLayout,
   vm: V1VirtualMachine,
   bootableVolumeSource: AddBootableVolumeState,
-  applyStorageProfileSettings: boolean,
-  claimPropertySets: ClaimPropertySets,
 ) => {
   const dataSource = produce(emptyDataSource, (draftDataSource) => {
     draftDataSource.metadata.name = bootableVolumeSource.bootableVolumeName;
@@ -46,13 +43,7 @@ export const createBootableVolumeFromDisk = async (
     };
   });
 
-  return createPVCBootableVolume(
-    bootableVolumeSource,
-    diskObj?.namespace,
-    applyStorageProfileSettings,
-    claimPropertySets,
-    dataSource,
-  );
+  return createPVCBootableVolume(bootableVolumeSource, diskObj?.namespace, dataSource);
 };
 
 const addDiskToVM = (draftVM: WritableDraft<V1VirtualMachine>, diskToPersist: V1Disk) => {


Reviews:
user: login: metalice
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T11:11:11Z
user: login: adamviktora
body: Looks good!

Only some details regarding styling. 
Another nit is in `ApplyStorageProfileSettings.scss`, the `align-items: anchor-center` doesn't work in Firefox, but `align-items: center` is fine.
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T09:08:10Z
user: login: rszwajko
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T09:31:48Z
user: login: rszwajko
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T11:10:55Z
user: login: adamviktora
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-15T13:08:25Z

Review comments:
diff_hunk: @@ -0,0 +1,89 @@
+/* eslint-disable @typescript-eslint/no-shadow */
+import { TFunction } from 'react-i18next';
+import { uniq } from 'lodash';
+
+import {
+  V1beta1StorageSpecAccessModesEnum,
+  V1beta1StorageSpecVolumeModeEnum,
+} from '@kubevirt-ui/kubevirt-api/kubevirt';
+import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation';
+import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
+
+export const tooltipForOtherRecommended = (priority: number, t: TFunction): string => {
+  switch (priority) {
+    case 1:
+      return t('The 2nd most suggested option in StorageProfile.');
+    case 2:
+      return t('The 3rd most suggested option in StorageProfile.');
+    default:
+      return t('The {{priority}}th most suggested option in StorageProfile.', {
+        priority: priority + 1,
+      });
+  }
+};
+
+export const fromPriorityToLabels = (
+  priority: number,
+  recommendationCount: number,
+  t: TFunction,
path: src/utils/components/ApplyStorageProfileSettings/utils.ts
user: login: metalice
body: no need for t, the console context of trans will trigger all plugins rerender, in this loading, t will be recalculated (what we talk about)
created_at: 2025-05-14T11:11:11Z
author_association: MEMBER
diff_hunk: @@ -1,33 +1,39 @@
 import React, { FC, useCallback, useEffect } from 'react';
-import { useFormContext } from 'react-hook-form';
 import { Trans } from 'react-i18next';
 import { Link } from 'react-router-dom-v5-compat';
 import { uniq } from 'lodash';
 
-import { V1beta1StorageSpecVolumeModeEnum } from '@kubevirt-ui/kubevirt-api/kubevirt';
-import HelpTextIcon from '@kubevirt-utils/components/HelpTextIcon/HelpTextIcon';
+import {
path: src/utils/components/ApplyStorageProfileSettings/VolumeMode.tsx
user: login: adamviktora
body: (detail not related to this change), but can we move the `{' '}` on line 70 of this file right after the `Learn more about` on line 68? (so the space is not underlined)
created_at: 2025-05-15T09:00:15Z
author_association: MEMBER
diff_hunk: @@ -131,9 +119,7 @@ const CreateBootableVolumeModal: FC<CreateBootableVolumeModalProps> = ({
           {t('Destination details')}
         </Title>
         <VolumeDestination
-          applyStorageProfileState={applyStorageProfileState}
path: src/views/virtualmachines/details/tabs/configuration/storage/components/modal/CreateBootableVolumeModal.tsx
user: login: adamviktora
body: VolumeDestination is missing Form styles in this modal, the whole Stack inside this TabModal should be wrapped in PatternFly `<Form>` to add the styling
created_at: 2025-05-15T09:02:32Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,89 @@
+/* eslint-disable @typescript-eslint/no-shadow */
+import { TFunction } from 'react-i18next';
+import { uniq } from 'lodash';
+
+import {
+  V1beta1StorageSpecAccessModesEnum,
+  V1beta1StorageSpecVolumeModeEnum,
+} from '@kubevirt-ui/kubevirt-api/kubevirt';
+import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation';
+import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
+
+export const tooltipForOtherRecommended = (priority: number, t: TFunction): string => {
+  switch (priority) {
+    case 1:
+      return t('The 2nd most suggested option in StorageProfile.');
+    case 2:
+      return t('The 3rd most suggested option in StorageProfile.');
+    default:
+      return t('The {{priority}}th most suggested option in StorageProfile.', {
+        priority: priority + 1,
+      });
+  }
+};
+
+export const fromPriorityToLabels = (
+  priority: number,
+  recommendationCount: number,
+  t: TFunction,
path: src/utils/components/ApplyStorageProfileSettings/utils.ts
user: login: rszwajko
body: @metalice I'll test that behavior and post the results here.
created_at: 2025-05-15T09:31:48Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,89 @@
+/* eslint-disable @typescript-eslint/no-shadow */
+import { TFunction } from 'react-i18next';
+import { uniq } from 'lodash';
+
+import {
+  V1beta1StorageSpecAccessModesEnum,
+  V1beta1StorageSpecVolumeModeEnum,
+} from '@kubevirt-ui/kubevirt-api/kubevirt';
+import { t } from '@kubevirt-utils/hooks/useKubevirtTranslation';
+import { ClaimPropertySets } from '@kubevirt-utils/types/storage';
+
+export const tooltipForOtherRecommended = (priority: number, t: TFunction): string => {
+  switch (priority) {
+    case 1:
+      return t('The 2nd most suggested option in StorageProfile.');
+    case 2:
+      return t('The 3rd most suggested option in StorageProfile.');
+    default:
+      return t('The {{priority}}th most suggested option in StorageProfile.', {
+        priority: priority + 1,
+      });
+  }
+};
+
+export const fromPriorityToLabels = (
+  priority: number,
+  recommendationCount: number,
+  t: TFunction,
path: src/utils/components/ApplyStorageProfileSettings/utils.ts
user: login: rszwajko
body: @metalice  it seems we have a bug here. Tested with https://github.com/kubevirt-ui/kubevirt-plugin/pull/2665 and as a result opened https://issues.redhat.com/browse/CNV-61822
created_at: 2025-05-15T11:10:54Z
author_association: MEMBER

PR comments:
user: login: openshift-ci-robot
created_at: 2025-05-12T18:10:59Z
body: @rszwajko: This pull request references [CNV-61181](https://issues.redhat.com//browse/CNV-61181) which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the bug to target the "4.20.0" version, but no target version was set.

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2653):

>
>
>## 📝 Description
>
>Follow-up to #2524
>
>Reference-Url: https://github.com/kubevirt-ui/kubevirt-plugin/pull/2524
>
>## 🎥 Demo
>
>### After
>
>![Screenshot From 2025-05-12 20-05-23](https://github.com/user-attachments/assets/073eb430-437f-4288-80f8-2945bd269306)
>![Screenshot From 2025-05-12 20-04-44](https://github.com/user-attachments/assets/0598856e-df01-4c9a-9905-3920f0b614b1)
>


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=kubevirt-ui%2Fkubevirt-plugin).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: COLLABORATOR
user: login: openshift-ci[bot]
created_at: 2025-05-12T18:11:06Z
body: Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with `/test all`
author_association: CONTRIBUTOR
user: login: openshift-ci-robot
created_at: 2025-05-13T12:35:50Z
body: @rszwajko: This pull request references [CNV-61181](https://issues.redhat.com//browse/CNV-61181) which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the bug to target the "4.20.0" version, but no target version was set.

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2653):

>
>## 📝 Description
>
>Follow-up to #2524
>
>Reference-Url: https://github.com/kubevirt-ui/kubevirt-plugin/pull/2524
>
>## 🎥 Demo
>### Before
>![image](https://github.com/user-attachments/assets/7b62cf5e-4bc4-46b9-8e75-7c6c71404cde)
>
>![image](https://github.com/user-attachments/assets/a24c50f8-d155-40d1-aba0-96c275cbf635)
>
>### After
>
>![Screenshot From 2025-05-12 20-05-23](https://github.com/user-attachments/assets/073eb430-437f-4288-80f8-2945bd269306)
>![Screenshot From 2025-05-12 20-04-44](https://github.com/user-attachments/assets/0598856e-df01-4c9a-9905-3920f0b614b1)
>


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=kubevirt-ui%2Fkubevirt-plugin).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: COLLABORATOR
user: login: openshift-ci-robot
created_at: 2025-05-13T12:50:29Z
body: @rszwajko: This pull request references [CNV-61181](https://issues.redhat.com//browse/CNV-61181) which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the bug to target the "4.20.0" version, but no target version was set.

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2653):

>## 📝 Description
>
>
>Follow-up to #2524
>
>Make ApplyStorageProfileSettings component independent from
>react-hook-form and re-use it for AddBootableVolumeModal and
>CreateBootableVolumeModal. Both modals rely on useState hook to keep
>the state.
>To better encapsulate the functionality, the component will take over
>the responsibility of clearing the volume/access modes after storage
>class change. The storage class name is stored as ref to avoid using
>setters as dependencies in the useEffect hook (component cannot assume
>their references will be stable).
>
>
>## 🎥 Demo
>### Before
>![image](https://github.com/user-attachments/assets/7b62cf5e-4bc4-46b9-8e75-7c6c71404cde)
>
>![image](https://github.com/user-attachments/assets/a24c50f8-d155-40d1-aba0-96c275cbf635)
>
>### After
>
>![Screenshot From 2025-05-12 20-05-23](https://github.com/user-attachments/assets/073eb430-437f-4288-80f8-2945bd269306)
>![Screenshot From 2025-05-12 20-04-44](https://github.com/user-attachments/assets/0598856e-df01-4c9a-9905-3920f0b614b1)
>


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=kubevirt-ui%2Fkubevirt-plugin).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: COLLABORATOR
user: login: openshift-ci-robot
created_at: 2025-05-15T12:55:30Z
body: @rszwajko: This pull request references [CNV-61181](https://issues.redhat.com//browse/CNV-61181) which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the bug to target the "4.20.0" version, but no target version was set.

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2653):

>## 📝 Description
>
>
>Follow-up to #2524
>
>Make ApplyStorageProfileSettings component independent from
>react-hook-form and re-use it for AddBootableVolumeModal and
>CreateBootableVolumeModal. Both modals rely on useState hook to keep
>the state.
>To better encapsulate the functionality, the component will take over
>the responsibility of clearing the volume/access modes after storage
>class change. The storage class name is stored as ref to avoid using
>setters as dependencies in the useEffect hook (component cannot assume
>their references will be stable).
>
>
>## 🎥 Demo
>### Before
>![image](https://github.com/user-attachments/assets/7b62cf5e-4bc4-46b9-8e75-7c6c71404cde)
>
>![image](https://github.com/user-attachments/assets/a24c50f8-d155-40d1-aba0-96c275cbf635)
>
>### After
>![image](https://github.com/user-attachments/assets/a4ae0a4b-13dd-44c1-be0a-74966a27f1e3)
>
>
>![Screenshot From 2025-05-12 20-04-44](https://github.com/user-attachments/assets/0598856e-df01-4c9a-9905-3920f0b614b1)
>


Instructions for interacting with me using PR comments are available [here](https://prow.ci.openshift.org/command-help?repo=kubevirt-ui%2Fkubevirt-plugin).  If you have questions or suggestions related to my behavior, please file an issue against the [openshift-eng/jira-lifecycle-plugin](https://github.com/openshift-eng/jira-lifecycle-plugin/issues/new) repository.
</details>
author_association: COLLABORATOR
user: login: openshift-ci[bot]
created_at: 2025-05-15T13:08:32Z
body: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubevirt-ui/kubevirt-plugin/pull/2653#pullrequestreview-2843632976" title="Approved">adamviktora</a>*, *<a href="https://github.com/kubevirt-ui/kubevirt-plugin/pull/2653#" title="Author self-approved">rszwajko</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubevirt-ui%2Fkubevirt-plugin).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubevirt-ui/kubevirt-plugin/blob/main/OWNERS)~~ [adamviktora,rszwajko]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: CONTRIBUTOR
user: login: gouyang
created_at: 2025-06-30T05:22:03Z
body: /cherry-pick release-4.18
author_association: MEMBER
user: login: openshift-cherrypick-robot
created_at: 2025-06-30T05:22:46Z
body: @gouyang: #2653 failed to apply on top of branch "release-4.18":
```
Applying: Surface StorageProfile options
error: mode change for src/utils/components/DiskModal/components/StorageProfileSettings/RecommendationLabel.tsx, which is not in current HEAD
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config advice.mergeConflict false"
Patch failed at 0001 Surface StorageProfile options

```

<details>

In response to [this](https://github.com/kubevirt-ui/kubevirt-plugin/pull/2653#issuecomment-3017841552):

>/cherry-pick release-4.18


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
author_association: COLLABORATOR