diff --git a/src/components/DeviceListTable.tsx b/src/components/DeviceListTable.tsx index 70872f5903..f769dc5e81 100644 --- a/src/components/DeviceListTable.tsx +++ b/src/components/DeviceListTable.tsx @@ -63,7 +63,7 @@ const DeviceListTable: FC = ({ configBaseURL, devices }) => { } if (isHostDiskDevice(device)) { - deviceType += " (host)"; + deviceType += " (host path)"; } } diff --git a/src/components/forms/DiskDeviceFormCustom.tsx b/src/components/forms/DiskDeviceFormCustom.tsx index 919e9b0350..280d8d4dca 100644 --- a/src/components/forms/DiskDeviceFormCustom.tsx +++ b/src/components/forms/DiskDeviceFormCustom.tsx @@ -22,7 +22,7 @@ import { isRootDisk, } from "util/instanceValidation"; import { ensureEditMode } from "util/instanceEdit"; -import { getExistingDeviceNames, isVolumeDevice } from "util/devices"; +import { getExistingDeviceNames, isVolume, isVolumeDevice } from "util/devices"; import { LxdProfile } from "types/profile"; import { focusField } from "util/formFields"; import AttachDiskDeviceBtn from "pages/storage/AttachDiskDeviceBtn"; @@ -40,13 +40,12 @@ const DiskDeviceFormCustom: FC = ({ formik, project, profiles }) => { const addDiskDevice = (device: LxdStorageVolume | LxdDiskDevice) => { const copy = [...formik.values.devices]; - const isVolume = "content_type" in device; const newDevice: FormDevice = { type: "disk", name: deduplicateName("disk-device", 1, existingDeviceNames), }; - if (isVolume) { + if (isVolume(device)) { newDevice.pool = device.pool; newDevice.source = device.name; newDevice.path = device.content_type === "filesystem" ? "" : undefined; @@ -67,8 +66,7 @@ const DiskDeviceFormCustom: FC = ({ formik, project, profiles }) => { formDiskDevice: FormDiskDevice, index: number, ) => { - const isVolume = "content_type" in diskDevice; - if (isVolume) { + if (isVolume(diskDevice)) { void formik.setFieldValue(`devices.${index}.pool`, diskDevice.pool); void formik.setFieldValue(`devices.${index}.source`, diskDevice.name); @@ -81,12 +79,10 @@ const DiskDeviceFormCustom: FC = ({ formik, project, profiles }) => { if (diskDevice.content_type === "block") { void formik.setFieldValue(`devices.${index}.path`, undefined); } - - return; + } else { + void formik.setFieldValue(`devices.${index}.source`, diskDevice.source); + void formik.setFieldValue(`devices.${index}.path`, diskDevice.path); } - - void formik.setFieldValue(`devices.${index}.source`, diskDevice.source); - void formik.setFieldValue(`devices.${index}.path`, diskDevice.path); }; const editButton = (fieldName: string) => ( @@ -138,75 +134,79 @@ const DiskDeviceFormCustom: FC = ({ formik, project, profiles }) => { }), ); - const volumeDeviceSource = getConfigurationRowBase({ - className: "no-border-top inherited-with-form", - configuration: ( - - ), - inherited: ( -
-
- - {item.pool} / {item.source} - + const volumeDeviceSource = () => + getConfigurationRowBase({ + className: "no-border-top inherited-with-form", + configuration: ( + + ), + inherited: ( +
+
+ + {item.pool} / {item.source} + +
+ { + ensureEditMode(formik); + changeDiskDevice(volume, item, index); + }} + buttonProps={{ + id: `devices.${index}.pool`, + appearance: "base", + className: "u-no-margin--bottom", + title: "Select storage volume", + dense: true, + }} + > + +
- { - ensureEditMode(formik); - changeDiskDevice(volume, item, index); - }} - buttonProps={{ - id: `devices.${index}.pool`, - appearance: "base", - className: "u-no-margin--bottom", - title: "Select storage volume", - dense: true, - }} - > - - -
- ), - override: "", - }); + ), + override: "", + }); - const hostDeviceSource = getConfigurationRowBase({ - className: "no-border-top inherited-with-form", - configuration: , - inherited: readOnly ? ( -
-
- {item.source} + const hostDeviceSource = () => + getConfigurationRowBase({ + className: "no-border-top inherited-with-form", + configuration: ( + + ), + inherited: readOnly ? ( +
+
+ {item.source} +
+ {editButton(`devices.${index}.source`)}
- {editButton(`devices.${index}.source`)} -
- ) : ( - { - void formik.setFieldValue( - `devices.${index}.source`, - e.target.value, - ); - }} - value={item.source} - type="text" - placeholder="Enter full host path (e.g. /data)" - className={!item.source ? undefined : "u-no-margin--bottom"} - error={!item.source ? "Host path is required" : undefined} - /> - ), - override: "", - }); + ) : ( + { + void formik.setFieldValue( + `devices.${index}.source`, + e.target.value, + ); + }} + value={item.source} + type="text" + placeholder="Enter full host path (e.g. /data)" + className={!item.source ? undefined : "u-no-margin--bottom"} + error={!item.source ? "Host path is required" : undefined} + /> + ), + override: "", + }); - rows.push(isVolumeDevice(item) ? volumeDeviceSource : hostDeviceSource); + rows.push(isVolumeDevice(item) ? volumeDeviceSource() : hostDeviceSource()); if (!isVolumeDevice(item) || item.path !== undefined) { const hasError = isDiskDeviceMountPointMissing(formik, index); diff --git a/src/pages/instances/actions/DetachDiskDeviceBtn.tsx b/src/pages/instances/actions/DetachDiskDeviceBtn.tsx index 93f46d38ec..86bbb01b96 100644 --- a/src/pages/instances/actions/DetachDiskDeviceBtn.tsx +++ b/src/pages/instances/actions/DetachDiskDeviceBtn.tsx @@ -10,10 +10,10 @@ const DetachDiskDeviceBtn: FC = ({ onDetach }) => { Are you sure you want to clear this disk attachment? diff --git a/src/pages/storage/AttachDiskDeviceModal.tsx b/src/pages/storage/AttachDiskDeviceModal.tsx index 43d4ea0892..d467a0d4ba 100644 --- a/src/pages/storage/AttachDiskDeviceModal.tsx +++ b/src/pages/storage/AttachDiskDeviceModal.tsx @@ -8,7 +8,7 @@ import { LxdStorageVolume } from "types/storage"; import { LxdDiskDevice } from "types/device"; import HostPathDeviceModal from "./HostPathDeviceModal"; -type DiskDeviceType = "custom volume" | "host path" | ""; +type DiskDeviceType = "custom volume" | "host path" | "choose type"; interface Props { close: () => void; @@ -23,7 +23,7 @@ const AttachDiskDeviceModal: FC = ({ project, onFinish, }) => { - const [type, setType] = useState(""); + const [type, setType] = useState("choose type"); const handleEscKey = (e: KeyboardEvent) => { if (e.key === "Escape") { @@ -32,45 +32,42 @@ const AttachDiskDeviceModal: FC = ({ }; const handleGoBack = () => { - if (type) { - setType(""); - return; - } + setType("choose type"); + return; }; - const modalTitle = !type ? ( - "Choose disk device type" - ) : ( - - ); + const modalTitle = + type === "choose type" ? ( + "Choose disk type" + ) : ( + + ); return ( <> - {!type && ( + {type === "choose type" && ( - {!type && ( -
- setType("custom volume")} - /> - setType("host path")} - /> -
- )} +
+ setType("custom volume")} + /> + setType("host path")} + /> +
)} @@ -80,6 +77,7 @@ const AttachDiskDeviceModal: FC = ({ project={project} onFinish={onFinish} onCancel={handleGoBack} + onClose={close} title={modalTitle} /> )} @@ -89,6 +87,7 @@ const AttachDiskDeviceModal: FC = ({ formik={formik} onFinish={onFinish} onCancel={handleGoBack} + onClose={close} title={modalTitle} /> )} diff --git a/src/pages/storage/CustomVolumeCreateModal.tsx b/src/pages/storage/CustomVolumeCreateModal.tsx index c4705b93e2..dbec2d5b06 100644 --- a/src/pages/storage/CustomVolumeCreateModal.tsx +++ b/src/pages/storage/CustomVolumeCreateModal.tsx @@ -117,7 +117,7 @@ const CustomVolumeCreateModal: FC = ({ className="u-no-margin--bottom" onClick={onCancel} > - Cancel + Back void; onCancel: () => void; + onClose: () => void; title?: ReactNode; } @@ -23,6 +24,7 @@ const CustomVolumeModal: FC = ({ project, onFinish, onCancel, + onClose, title, }) => { const [content, setContent] = useState(SELECT_VOLUME); @@ -45,9 +47,9 @@ const CustomVolumeModal: FC = ({ if (content === CREATE_VOLUME) { modalTitle = title ? ( ) : ( "Create volume" @@ -55,7 +57,7 @@ const CustomVolumeModal: FC = ({ } return ( - + {content === SELECT_VOLUME && ( = ({ onFinish={onFinish} onCancel={onCancel} onCreate={() => setContent(CREATE_VOLUME)} + hasPrevStep={!!title} /> )} {content === CREATE_VOLUME && ( diff --git a/src/pages/storage/CustomVolumeSelectBtn.tsx b/src/pages/storage/CustomVolumeSelectBtn.tsx index e331ca7a6e..4f46b3f3f4 100644 --- a/src/pages/storage/CustomVolumeSelectBtn.tsx +++ b/src/pages/storage/CustomVolumeSelectBtn.tsx @@ -22,8 +22,6 @@ const CustomVolumeSelectBtn: FC = ({ }) => { const { openPortal, closePortal, isOpen, Portal } = usePortal(); - const handleCancel = () => closePortal(); - const handleFinish = (volume: LxdStorageVolume) => { setValue(volume); closePortal(); @@ -40,7 +38,8 @@ const CustomVolumeSelectBtn: FC = ({ formik={formik} project={project} onFinish={handleFinish} - onCancel={handleCancel} + onCancel={closePortal} + onClose={closePortal} /> )} diff --git a/src/pages/storage/CustomVolumeSelectModal.tsx b/src/pages/storage/CustomVolumeSelectModal.tsx index dfde433e41..8897389e32 100644 --- a/src/pages/storage/CustomVolumeSelectModal.tsx +++ b/src/pages/storage/CustomVolumeSelectModal.tsx @@ -18,6 +18,7 @@ interface Props { onFinish: (volume: LxdStorageVolume) => void; onCancel: () => void; onCreate: () => void; + hasPrevStep?: boolean; } const CustomVolumeSelectModal: FC = ({ @@ -27,6 +28,7 @@ const CustomVolumeSelectModal: FC = ({ onFinish, onCancel, onCreate, + hasPrevStep, }) => { const notify = useNotify(); const { hasStorageVolumesAll } = useSupportedFeatures(); @@ -186,7 +188,7 @@ const CustomVolumeSelectModal: FC = ({ onClick={onCancel} appearance="base" > - Cancel + {hasPrevStep ? "Back" : "Cancel"}