Skip to content

Commit

Permalink
Merge pull request #2061 from avivtur/move-disk-source
Browse files Browse the repository at this point in the history
Move disk source outside the add disk modal dialog
  • Loading branch information
openshift-merge-bot[bot] authored Jul 17, 2024
2 parents c5f9c60 + 2992062 commit d5e7d3d
Show file tree
Hide file tree
Showing 18 changed files with 213 additions and 138 deletions.
2 changes: 2 additions & 0 deletions locales/en/plugin__kubevirt-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@
"Container (Ephemeral)": "Container (Ephemeral)",
"Container disk": "Container disk",
"Container Image": "Container Image",
"Container image or PVC": "Container image or PVC",
"Container is required.": "Container is required.",
"Content from container registry.": "Content from container registry.",
"Copied": "Copied",
Expand Down Expand Up @@ -1286,6 +1287,7 @@
"URL": "URL",
"URL (creates PVC)": "URL (creates PVC)",
"URL is required": "URL is required",
"URL, Registry or Upload": "URL, Registry or Upload",
"Usage": "Usage",
"Use a persistent volume claim available on the cluster.": "Use a persistent volume claim available on the cluster.",
"Use BIOS when bootloading the guest OS (Default)": "Use BIOS when bootloading the guest OS (Default)",
Expand Down
17 changes: 7 additions & 10 deletions src/utils/components/DiskModal/DiskModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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 { getBootDisk } from '@kubevirt-utils/resources/vm';
import { generatePrettyName, isEmpty, kubevirtConsole } from '@kubevirt-utils/utils/utils';
import { generatePrettyName, kubevirtConsole } from '@kubevirt-utils/utils/utils';
import { Form } from '@patternfly/react-core';
import { isRunning } from '@virtualmachines/utils';

Expand All @@ -17,7 +17,7 @@ import BootSourceCheckbox from './components/BootSourceCheckbox/BootSourceCheckb
import DiskInterfaceSelect from './components/DiskInterfaceSelect/DiskInterfaceSelect';
import DiskNameInput from './components/DiskNameInput/DiskNameInput';
import DiskSizeInput from './components/DiskSizeInput/DiskSizeInput';
import DiskSourceSelect from './components/DiskSourceSelect/DiskSourceSelect';
import { getSelectedDiskSourceComponent } from './components/DiskSourceSelect/utils/utils';
import DiskTypeSelect from './components/DiskTypeSelect/DiskTypeSelect';
import StorageClassAndPreallocation from './components/StorageClassAndPreallocation/StorageClassAndPreallocation';
import { getInitialStateDiskForm } from './utils/constants';
Expand All @@ -33,9 +33,9 @@ const DiskModal: FC<DiskModalProps> = ({
createOwnerReference = true,
headerText,
initialFormData = null,
isEditDisk = false,
isEditingCreatedDisk = false,
isOpen,
isTemplate = false,
onClose,
onSubmit,
onUploadedDataVolume,
Expand All @@ -58,6 +58,8 @@ const DiskModal: FC<DiskModalProps> = ({
handleSubmit,
} = methods;

const diskSource = initialFormData?.diskSource;

return (
<FormProvider {...methods}>
<TabModal
Expand All @@ -71,7 +73,7 @@ const DiskModal: FC<DiskModalProps> = ({
handleSubmit((data) => {
if (isEditingCreatedDisk) return editVMDisk(vm, initialFormData, data, onSubmit);

if (!isEmpty(initialFormData))
if (isEditDisk)
return editDisk(initialFormData, data, uploadData, {
createOwnerReference,
onSubmit,
Expand Down Expand Up @@ -105,12 +107,7 @@ const DiskModal: FC<DiskModalProps> = ({
isDisabled={isVMRunning}
/>
<DiskNameInput />
<DiskSourceSelect
isEditingCreatedDisk={isEditingCreatedDisk}
isTemplate={isTemplate}
relevantUpload={upload}
vm={vm}
/>
{getSelectedDiskSourceComponent(vm, upload)[diskSource]}
<DiskSizeInput isEditingCreatedDisk={isEditingCreatedDisk} />
<DiskTypeSelect isVMRunning={isVMRunning} />
<DiskInterfaceSelect isVMRunning={isVMRunning} />
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React, { FC } from 'react';
import { useFormContext } from 'react-hook-form';

import { DiskFormState, SourceTypes } from '@kubevirt-utils/components/DiskModal/utils/types';
import { diskTypes } from '@kubevirt-utils/resources/vm/utils/disk/constants';
import { SourceTypes } from '@kubevirt-utils/components/DiskModal/utils/types';
import { SelectList, SelectOption } from '@patternfly/react-core';

import { diskSourceFieldID } from '../../utils/constants';
Expand All @@ -17,20 +15,15 @@ type DiskSourceSelectOptionsProps = {

const DiskSourceSelectOptions: FC<DiskSourceSelectOptionsProps> = ({
isEditingCreatedDisk,
isTemplate,
isTemplate = false,
isVMRunning,
items,
}) => {
const { watch } = useFormContext<DiskFormState>();

const diskType = watch('diskType');
const isCDROMType = diskType === diskTypes.cdrom;
return (
<SelectList>
{items.map(({ description, id, label }) => {
const isDisabled =
(isVMRunning && id === SourceTypes.EPHEMERAL) ||
(isCDROMType && id === SourceTypes.BLANK) ||
(isTemplate && id === SourceTypes.UPLOAD);
return (
<SelectOption
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const optionLabelMapper: { [key in SourceTypes]: string } = {
};

export const attachExistingGroupOptions: DiskSourceOptionGroup = {
description: t('Container image or PVC'),
groupLabel: t('Attach existing'),
items: [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { ReactNode } from 'react';

import { SourceTypes } from '@kubevirt-utils/components/DiskModal/utils/types';

export type DiskSourceOptionGroupItem = {
description?: string;
id: SourceTypes;
label: string;
label: ReactNode | string;
};

export type DiskSourceOptionGroup = {
description?: string;
groupLabel?: string;
items: DiskSourceOptionGroupItem[];
};
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const getSelectedDiskSourceComponent = (
};

export const getImportGroupOptions = (isTemplate: boolean): DiskSourceOptionGroup => ({
description: t('URL, Registry or Upload'),
groupLabel: t('Import'),
items: [
{
Expand All @@ -60,10 +61,14 @@ export const getImportGroupOptions = (isTemplate: boolean): DiskSourceOptionGrou
id: SourceTypes.REGISTRY,
label: optionLabelMapper[SourceTypes.REGISTRY],
},
!isTemplate && {
id: SourceTypes.UPLOAD,
label: optionLabelMapper[SourceTypes.UPLOAD],
},
...(isTemplate
? []
: [
{
id: SourceTypes.UPLOAD,
label: optionLabelMapper[SourceTypes.UPLOAD],
},
]),
],
});

Expand Down
2 changes: 1 addition & 1 deletion src/utils/components/DiskModal/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ export type DiskModalProps = {
createOwnerReference?: boolean;
headerText: string;
initialFormData?: DiskFormState;
isEditDisk?: boolean;
isEditingCreatedDisk?: boolean;
isOpen: boolean;
isTemplate?: boolean;
onClose: () => void;
onSubmit: (updatedVM: V1VirtualMachine) => Promise<V1VirtualMachine | void>;
onUploadedDataVolume?: (dataVolume: V1beta1DataVolume) => void;
Expand Down
90 changes: 90 additions & 0 deletions src/utils/components/DiskSourceFlyoutMenu/DiskSourceFlyoutMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, { FC, useRef, useState } from 'react';

import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation';
import {
Menu,
MenuContainer,
MenuContent,
MenuItem,
MenuList,
MenuToggle,
} from '@patternfly/react-core';

import { getDiskSourceOptionGroups } from '../DiskModal/components/DiskSourceSelect/utils/utils';
import { SourceTypes } from '../DiskModal/utils/types';

import FlyoutItem from './components/FlyoutItem/FlyoutItem';
import { DiskSourceFlyoutMenuProps } from './utils/types';

const DiskSourceFlyoutMenu: FC<DiskSourceFlyoutMenuProps> = ({
className,
isTemplate = false,
onSelect,
}) => {
const { t } = useKubevirtTranslation();
const [isOpen, setIsOpen] = useState<boolean>(false);
const menuRef = useRef<HTMLDivElement>(null);
const toggleRef = useRef<HTMLButtonElement>(null);

const options = getDiskSourceOptionGroups(isTemplate);

const onSelectSource = (value: SourceTypes) => {
onSelect(value);
setIsOpen(false);
};

const toggle = (
<MenuToggle
className={className}
isExpanded={isOpen}
onClick={() => setIsOpen((open) => !open)}
ref={toggleRef}
variant="primary"
>
{t('Add disk')}
</MenuToggle>
);

const menu = (
<Menu containsFlyout ref={menuRef}>
<MenuContent>
<MenuList>
{options?.map(({ description, groupLabel, items }) => {
const isFlyout = items?.length > 1;
return isFlyout ? (
<MenuItem
description={description}
flyoutMenu={<FlyoutItem items={items} onSelect={onSelectSource} />}
itemId={groupLabel}
>
{groupLabel}
</MenuItem>
) : (
<MenuItem
description={description}
itemId={items?.[0]?.id}
onClick={() => onSelectSource(items?.[0]?.id)}
>
{items?.[0]?.label}
</MenuItem>
);
})}
</MenuList>
</MenuContent>
</Menu>
);

return (
<MenuContainer
isOpen={isOpen}
menu={menu}
menuRef={menuRef}
onOpenChange={(open) => setIsOpen(open)}
popperProps={{ width: '250px' }}
toggle={toggle}
toggleRef={toggleRef}
/>
);
};

export default DiskSourceFlyoutMenu;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.flyout-item {
min-width: 250px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { FC } from 'react';

import { DiskSourceOptionGroupItem } from '@kubevirt-utils/components/DiskModal/components/DiskSourceSelect/utils/types';
import { Menu, MenuContent, MenuItem, MenuList } from '@patternfly/react-core';

import { DiskSourceFlyoutMenuProps } from '../../utils/types';

import './FlyoutItem.scss';

type FlyoutItemProps = {
items: DiskSourceOptionGroupItem[];
onSelect: DiskSourceFlyoutMenuProps['onSelect'];
};
const FlyoutItem: FC<FlyoutItemProps> = ({ items, onSelect }) => (
<Menu className="flyout-item">
<MenuContent>
<MenuList>
{items?.map(({ description, id, label }) => (
<MenuItem description={description} itemId={id} key={id} onClick={() => onSelect(id)}>
{label}
</MenuItem>
))}
</MenuList>
</MenuContent>
</Menu>
);

export default FlyoutItem;
7 changes: 7 additions & 0 deletions src/utils/components/DiskSourceFlyoutMenu/utils/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SourceTypes } from '@kubevirt-utils/components/DiskModal/utils/types';

export type DiskSourceFlyoutMenuProps = {
className?: string;
isTemplate?: boolean;
onSelect: (value: SourceTypes) => void;
};
Loading

0 comments on commit d5e7d3d

Please sign in to comment.