Skip to content

Conversation

@batyana
Copy link
Member

@batyana batyana commented Feb 11, 2026

📝 Description

  • Redesigned the Add CD-ROM modal UI: replaced the dropdown/checkbox interface with three radio buttons (Mount existing ISO, Upload new ISO, Leave empty drive) for a more intuitive experience.
  • For hotpluggable VMs, the modal now closes immediately when an upload starts. A dynamic alert on the Storage tab tracks the upload status (uploading / success / error).
  • Added the option to add a CD-ROM with an empty drive. The option is disabled when the DeclarativeHotplugVolumes feature gate is not enabled.
  • Extracted CD-ROM submit logic from AddCDROMModal into a submitCDROM helper in submit.ts, keeping the component focused on form state and rendering.
  • Extracted upload alert state management into a useUploadAlert hook and moved alert configuration to storage/utils/constants.ts.
  • Added a createMutableUploadData helper in helpers.ts to safely handle fire-and-forget uploads without mutating frozen form data.

🎥 Demo

Screenshot at Feb 11 14-30-08
Screen.Recording.2026-02-11.at.14.26.21.mov

Summary by CodeRabbit

  • New Features
    • Enhanced CD-ROM configuration with three mounting options: mount existing ISO, upload new ISO, or leave drive empty
    • Added upload start callback and upload flow handling to surface upload state
    • Added upload progress/status alerts (uploading, success, error) for improved feedback
    • Expanded localization for CD-ROM/ISO operations in English, Spanish, French, Japanese, Korean, and Chinese

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Feb 11, 2026

@batyana: This pull request references CNV-77263 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 story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

📝 Description

  • Redesigned the Add CD-ROM modal UI: replaced the dropdown/checkbox interface with three radio buttons (Mount existing ISO, Upload new ISO, Leave empty drive) for a more intuitive experience.
  • For hotpluggable VMs, the modal now closes immediately when an upload starts. A dynamic alert on the Storage tab tracks the upload status (uploading / success / error).
  • Added the option to add a CD-ROM with an empty drive. The option is disabled when the DeclarativeHotplugVolumes feature gate is not enabled.
  • Extracted CD-ROM submit logic from AddCDROMModal into a submitCDROM helper in submit.ts, keeping the component focused on form state and rendering.
  • Extracted upload alert state management into a useUploadAlert hook and moved alert configuration to storage/utils/constants.ts.
  • Added a createMutableUploadData helper in helpers.ts to safely handle fire-and-forget uploads without mutating frozen form data.

🎥 Demo

Screenshot at Feb 11 14-30-08
Screen.Recording.2026-02-11.at.14.26.21.mov

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 11, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: batyana
Once this PR has been reviewed and has the lgtm label, please assign rszwajko for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

Refactors CD-ROM modal to a radio-based source selector (Mount ISO / Upload / Empty), adds submitCDROM and upload helpers, threads a new onUploadStarted callback through DiskModal → DiskList → StorageTab, introduces upload alert state and translations across locale files.

Changes

Cohort / File(s) Summary
Localization Files
locales/en/plugin__kubevirt-plugin.json, locales/es/plugin__kubevirt-plugin.json, locales/fr/plugin__kubevirt-plugin.json, locales/ja/plugin__kubevirt-plugin.json, locales/ko/plugin__kubevirt-plugin.json, locales/zh/plugin__kubevirt-plugin.json
Added CD‑ROM / ISO translation keys (e.g., "CD‑ROM source", "Leave empty drive", "Mount existing ISO", "Select ISO file", "Upload new ISO", and a DeclarativeHotplugVolumes feature‑gate message); minor removals/duplications in some locales.
AddCDROMModal refactor
src/utils/components/DiskModal/AddCDROMModal.tsx
Reworked UI to three radio options, removed legacy upload-mode flow, now calls submitCDROM; added onUploadStarted prop and PendingChangesAlert; updated conditional UI for ISO pick/upload/empty.
DiskModal component & types
src/utils/components/DiskModal/DiskModal.tsx, src/utils/components/DiskModal/utils/types.ts
Added onUploadStarted?: (uploadPromise: Promise<unknown>) => void to DiskModal props and forwarded it to child Modal.
DiskModal utils
src/utils/components/DiskModal/utils/constants.ts, src/utils/components/DiskModal/utils/helpers.ts, src/utils/components/DiskModal/utils/submit.ts
Added UPLOAD_MODE_EMPTY constant; new createMutableUploadData helper; new SubmitCDROMInput type and submitCDROM function handling ISO selection, upload (hot‑pluggable or not), empty drive, upload callbacks, and disk attach flow.
DiskSourceUploadPVC tweak
src/utils/components/DiskModal/components/DiskSourceSelect/components/DiskSourceUploadPVC/DiskSourceUploadPVC.tsx
Changed label defaulting to use nullish coalescing to preserve explicit empty-string labels.
Mount CD‑ROM form hook
src/views/virtualmachines/details/tabs/configuration/storage/components/modal/hooks/useMountCDROMForm.ts
Extended uploadMode to include UPLOAD_MODE_EMPTY; added handleEmptyDriveSelection and exposed it in the hook API.
DiskList prop passthrough
src/views/virtualmachines/details/tabs/configuration/storage/components/tables/disk/DiskList.tsx
Added optional onUploadStarted prop to DiskListProps and forwarded it to DiskModal via DiskSourceSelect.
Upload alert & constants
src/views/virtualmachines/details/tabs/configuration/storage/components/hooks/useUploadAlert.ts, src/views/virtualmachines/details/tabs/configuration/storage/utils/constants.ts
New useUploadAlert hook managing upload lifecycle (uploading/success/error) and uploadAlertConfig mapping with PatternFly variants; exposes alertConfig, dismissAlert, onUploadStarted, uploadError.
StorageTab integration
src/views/virtualmachines/details/tabs/configuration/storage/StorageTab.tsx
Integrated useUploadAlert, renders conditional Alert with upload feedback, passes onUploadStarted to DiskList, added translation hook usage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • vojtechszocs
  • gouyang
  • upalatucci
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: redesigning the CD-ROM modal with new UI components and interactions.
Description check ✅ Passed The description covers the template structure and includes comprehensive details about the UI redesign, implementation approach, and feature additions with a demo screenshot.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/views/virtualmachines/details/tabs/configuration/storage/components/modal/hooks/useMountCDROMForm.ts (1)

74-74: isFormValid in the hook doesn't account for the new empty-drive mode.

isFormValid will return false when "Leave empty drive" is selected because neither selectedISO nor uploadFile?.filename will be set. The AddCDROMModal component computes its own validity check (line 92) that includes emptyDriveSelected, so this isn't a runtime bug, but it makes the hook's isFormValid misleading for any future consumer.

Consider updating it:

Proposed fix
-  const isFormValid = Boolean(selectedISO || uploadFile?.filename);
+  const isFormValid = Boolean(selectedISO || uploadFile?.filename || uploadMode === UPLOAD_MODE_EMPTY);
src/utils/components/DiskModal/utils/submit.ts (1)

206-215: Missing explicit return type on submitCDROM.

As per coding guidelines, always explicitly define return types for functions. The SubmitCDROMInput type is well-defined, but the function itself lacks a return type annotation.

Proposed fix
-export const submitCDROM = async (
+export const submitCDROM = async (
   data: V1DiskFormState,
   {
     ...
   }: SubmitCDROMInput,
-) => {
+): Promise<V1VirtualMachine | void> => {

As per coding guidelines: "Always explicitly define return types for functions rather than relying on TypeScript type inference."

src/utils/components/DiskModal/AddCDROMModal.tsx (1)

62-64: Consider using named constants instead of inline empty-string comparisons for upload mode.

existingISOSelected checks mountUploadMode === '' which relies on the initial default value. A named constant (e.g., UPLOAD_MODE_INITIAL or UPLOAD_MODE_NONE) would be more self-documenting and resilient to default-value changes.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Feb 11, 2026

@batyana: This pull request references CNV-77263 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 story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

📝 Description

  • Redesigned the Add CD-ROM modal UI: replaced the dropdown/checkbox interface with three radio buttons (Mount existing ISO, Upload new ISO, Leave empty drive) for a more intuitive experience.
  • For hotpluggable VMs, the modal now closes immediately when an upload starts. A dynamic alert on the Storage tab tracks the upload status (uploading / success / error).
  • Added the option to add a CD-ROM with an empty drive. The option is disabled when the DeclarativeHotplugVolumes feature gate is not enabled.
  • Extracted CD-ROM submit logic from AddCDROMModal into a submitCDROM helper in submit.ts, keeping the component focused on form state and rendering.
  • Extracted upload alert state management into a useUploadAlert hook and moved alert configuration to storage/utils/constants.ts.
  • Added a createMutableUploadData helper in helpers.ts to safely handle fire-and-forget uploads without mutating frozen form data.

🎥 Demo

Screenshot at Feb 11 14-30-08
Screen.Recording.2026-02-11.at.14.26.21.mov

Summary by CodeRabbit

Release Notes

  • New Features
  • Enhanced CD-ROM configuration with three mounting options: mount existing ISO, upload new ISO, or leave empty drive
  • Added upload progress and status alerts (uploading, success, error) for improved user feedback during ISO uploads
  • Expanded localization support for CD-ROM and ISO operations across English, Spanish, French, Japanese, Korean, and Chinese

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/views/virtualmachines/details/tabs/configuration/storage/components/modal/hooks/useMountCDROMForm.ts (1)

74-74: ⚠️ Potential issue | 🟠 Major

isFormValid doesn't account for the empty drive mode — "Add" button will be disabled.

When the user selects "Leave empty drive", selectedISO is '' and uploadFile is null, so isFormValid evaluates to false. The submit button will remain disabled for the empty drive option.

🐛 Proposed fix
-  const isFormValid = Boolean(selectedISO || uploadFile?.filename);
+  const isFormValid = Boolean(selectedISO || uploadFile?.filename || uploadMode === UPLOAD_MODE_EMPTY);
🤖 Fix all issues with AI agents
In `@src/utils/components/DiskModal/utils/helpers.ts`:
- Around line 330-339: createMutableUploadData currently always fabricates a
dataVolumeTemplate when data.dataVolumeTemplate is undefined; change it to guard
for existence of data.dataVolumeTemplate and only shallow-copy/modify
spec.source when the template exists—i.e., in createMutableUploadData, detect if
data.dataVolumeTemplate is truthy and then return a new object with
dataVolumeTemplate: { ...data.dataVolumeTemplate, spec: {
...data.dataVolumeTemplate.spec, source: {
...data.dataVolumeTemplate.spec?.source } } }, otherwise return the original
data unchanged (or copy other fields without adding dataVolumeTemplate);
reference createMutableUploadData and the dataVolumeTemplate/spec/source
properties to locate the change.

In `@src/utils/components/DiskModal/utils/submit.ts`:
- Around line 239-256: The hot-plug upload path creates the DataVolume with a
generated name inside uploadDataVolume (which uses generateUploadDiskName) but
then reads dvName from data.dataVolumeTemplate?.metadata?.name (which may
instead have been set by createDataVolumeName), causing a mismatch; fix by using
the DataVolume returned by uploadDataVolume to update
data.dataVolumeTemplate.metadata.name and data.volume.dataVolume.name (or
replace data.dataVolumeTemplate and data.volume.dataVolume with the returned
object) inside the uploadPromise.then handler (and keep calling
onUploadedDataVolume/uploadStarted as before) so the VM volume references the
actual uploaded DataVolume name generated by uploadDataVolume.

In
`@src/views/virtualmachines/details/tabs/configuration/storage/components/hooks/useUploadAlert.ts`:
- Around line 8-23: The hook useUploadAlert should declare explicit return types
and its internal handlers should be typed: add a return type for useUploadAlert
(including uploadStatus, uploadError, onUploadStarted, dismissAlert), annotate
onUploadStarted as (uploadPromise: Promise<unknown>) => void and dismissAlert as
() => void, and change the catch handler parameter to err: unknown and narrow it
(e.g., if (err instanceof Error) setUploadError(err.message) else
setUploadError(String(err))) before calling setUploadError; keep using
setUploadStatus('error'/'success'/'uploading') as before.
🧹 Nitpick comments (4)
src/views/virtualmachines/details/tabs/configuration/storage/utils/constants.ts (1)

5-24: Rename uploadAlertConfig to uppercase constant style.

This is a utility constant and should follow the repo’s uppercase underscore naming convention. Update call sites accordingly.

Proposed fix
-export const uploadAlertConfig: Record<
+export const UPLOAD_ALERT_CONFIG: Record<
   UploadAlertStatus,
   { body: string; title: string; variant: AlertVariant }
 > = {

As per coding guidelines, "Define constants in utility files with uppercase and underscore-separated naming (e.g., API_URL)."

src/utils/components/DiskModal/utils/submit.ts (2)

217-274: Missing explicit return type on submitCDROM.

Per coding guidelines, functions should always have explicit return types rather than relying on inference.

Proposed fix
 export const submitCDROM = async (
   data: V1DiskFormState,
   {
     isHotPluggable,
     onSubmit,
     onUploadedDataVolume,
     onUploadStarted,
     selectedISO,
     uploadData: uploadDataFn,
     uploadEnabled,
     vm,
   }: SubmitCDROMInput,
-) => {
+): Promise<V1VirtualMachine | void> => {

As per coding guidelines, "Always explicitly define return types for functions rather than relying on TypeScript type inference."


230-269: Direct mutation of data parameter may cause issues.

submitCDROM mutates its data parameter in-place (delete data.dataVolumeTemplate, data.volume = ..., etc.). If the caller or any .then() handler references data after this call, it will see the mutated state. Consider working on a local copy instead of mutating the input.

src/utils/components/DiskModal/AddCDROMModal.tsx (1)

94-104: Wrap handleModalSubmit in useCallback and add an explicit return type.

handleModalSubmit is recreated every render and passed as onSubmit to TabModal. This can trigger unnecessary child re-renders. Per the project's coding guidelines, memoization tools should be used, and functions should have explicit return types.

♻️ Suggested refactor
-  const handleModalSubmit = () =>
-    submitCDROM(getValues(), {
+  const handleModalSubmit = useCallback((): Promise<void> =>
+    submitCDROM(getValues(), {
       isHotPluggable,
       onSubmit,
       onUploadedDataVolume,
       onUploadStarted,
       selectedISO,
       uploadData,
       uploadEnabled,
       vm,
-    });
+    }), [getValues, isHotPluggable, onSubmit, onUploadedDataVolume, onUploadStarted, selectedISO, uploadData, uploadEnabled, vm]);

You'll also need to add useCallback to the React import on line 1:

import React, { FC, useCallback, useEffect } from 'react';

As per coding guidelines: "Use React's memoization tools (React.memo, useMemo, useCallback) to avoid unnecessary re-renders." and "Always explicitly define return types for functions rather than relying on TypeScript type inference."

Comment on lines +8 to +23
export const useUploadAlert = () => {
const [uploadStatus, setUploadStatus] = useState<null | UploadAlertStatus>(null);
const [uploadError, setUploadError] = useState('');

const onUploadStarted = (uploadPromise: Promise<unknown>) => {
setUploadStatus('uploading');
setUploadError('');
uploadPromise
.then(() => setUploadStatus('success'))
.catch((err) => {
setUploadStatus('error');
setUploadError(err?.message || '');
});
};

const dismissAlert = () => setUploadStatus(null);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n "src/views/virtualmachines/details/tabs/configuration/storage/components/hooks/useUploadAlert.ts"

Repository: kubevirt-ui/kubevirt-plugin

Length of output: 1117


🏁 Script executed:

cat -n "src/views/virtualmachines/details/tabs/configuration/storage/utils/constants.ts" | head -50

Repository: kubevirt-ui/kubevirt-plugin

Length of output: 951


Add explicit return types and type the catch handler error as unknown.

Guidelines require explicit function return types for all functions in TypeScript files. Additionally, the caught error must be typed as unknown and narrowed to avoid implicit any.

Suggested fix
+type UploadAlertConfig = (typeof uploadAlertConfig)[UploadAlertStatus];
+
+type UseUploadAlertResult = {
+  alertConfig: UploadAlertConfig | null;
+  dismissAlert: () => void;
+  onUploadStarted: (uploadPromise: Promise<unknown>) => void;
+  uploadError: string;
+};
+
-export const useUploadAlert = () => {
+export const useUploadAlert = (): UseUploadAlertResult => {
   const [uploadStatus, setUploadStatus] = useState<null | UploadAlertStatus>(null);
   const [uploadError, setUploadError] = useState('');
 
-  const onUploadStarted = (uploadPromise: Promise<unknown>) => {
+  const onUploadStarted = (uploadPromise: Promise<unknown>): void => {
     setUploadStatus('uploading');
     setUploadError('');
     uploadPromise
       .then(() => setUploadStatus('success'))
-      .catch((err) => {
+      .catch((err: unknown) => {
         setUploadStatus('error');
-        setUploadError(err?.message || '');
+        setUploadError(err instanceof Error ? err.message : '');
       });
   };
 
-  const dismissAlert = () => setUploadStatus(null);
+  const dismissAlert = (): void => setUploadStatus(null);
🤖 Prompt for AI Agents
In
`@src/views/virtualmachines/details/tabs/configuration/storage/components/hooks/useUploadAlert.ts`
around lines 8 - 23, The hook useUploadAlert should declare explicit return
types and its internal handlers should be typed: add a return type for
useUploadAlert (including uploadStatus, uploadError, onUploadStarted,
dismissAlert), annotate onUploadStarted as (uploadPromise: Promise<unknown>) =>
void and dismissAlert as () => void, and change the catch handler parameter to
err: unknown and narrow it (e.g., if (err instanceof Error)
setUploadError(err.message) else setUploadError(String(err))) before calling
setUploadError; keep using setUploadStatus('error'/'success'/'uploading') as
before.

@batyana batyana force-pushed the CNV-77263-redesign-add-cd-rom-modal branch from ab0acd4 to ee93633 Compare February 11, 2026 13:11
@openshift-ci-robot
Copy link
Collaborator

openshift-ci-robot commented Feb 11, 2026

@batyana: This pull request references CNV-77263 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 story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

📝 Description

  • Redesigned the Add CD-ROM modal UI: replaced the dropdown/checkbox interface with three radio buttons (Mount existing ISO, Upload new ISO, Leave empty drive) for a more intuitive experience.
  • For hotpluggable VMs, the modal now closes immediately when an upload starts. A dynamic alert on the Storage tab tracks the upload status (uploading / success / error).
  • Added the option to add a CD-ROM with an empty drive. The option is disabled when the DeclarativeHotplugVolumes feature gate is not enabled.
  • Extracted CD-ROM submit logic from AddCDROMModal into a submitCDROM helper in submit.ts, keeping the component focused on form state and rendering.
  • Extracted upload alert state management into a useUploadAlert hook and moved alert configuration to storage/utils/constants.ts.
  • Added a createMutableUploadData helper in helpers.ts to safely handle fire-and-forget uploads without mutating frozen form data.

🎥 Demo

Screenshot at Feb 11 14-30-08
Screen.Recording.2026-02-11.at.14.26.21.mov

Summary by CodeRabbit

  • New Features
  • Enhanced CD-ROM configuration with three mounting options: mount existing ISO, upload new ISO, or leave drive empty
  • Added upload start callback and upload flow handling to surface upload state
  • Added upload progress/status alerts (uploading, success, error) for improved feedback
  • Expanded localization for CD-ROM/ISO operations in English, Spanish, French, Japanese, Korean, and Chinese

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@galkremer1
Copy link
Member

@yfrimanm - do you think we should use Requires enabling advanced CD-ROM features instead of Requires the DeclarativeHotplugVolumes feature gate to be enabled.?
We can also link directly to k8s/all-namespaces/virtualization-overview/settings/features (If the user is an admin, but I am not sure if we want to over complicate it).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants