diff --git a/web/src/components/storage/DriveEditor.tsx b/web/src/components/storage/DriveEditor.tsx index e6c6626257..37a67c925a 100644 --- a/web/src/components/storage/DriveEditor.tsx +++ b/web/src/components/storage/DriveEditor.tsx @@ -29,7 +29,7 @@ import { useAvailableDevices } from "~/queries/storage"; import { configModel } from "~/api/storage/types"; import { StorageDevice } from "~/types/storage"; import { STORAGE as PATHS } from "~/routes/paths"; -import { useDrive } from "~/queries/storage/config-model"; +import { useDrive, usePartition } from "~/queries/storage/config-model"; import * as driveUtils from "~/components/storage/utils/drive"; import { typeDescription, contentDescription } from "~/components/storage/utils/device"; import { Icon } from "../layout"; @@ -567,15 +567,41 @@ const PartitionsNoContentSelector = () => { ); }; +const PartitionMenuItem = ({ driveName, mountPath }) => { + const { onDelete } = usePartition(driveName, mountPath); + + return ( + + } + actionId={`edit-${mountPath}`} + aria-label={`Edit ${mountPath}`} + /> + } + actionId={`delete-${mountPath}`} + aria-label={`Delete ${mountPath}`} + onClick={onDelete} + /> + + } + > + {mountPath} + + ); +}; + const PartitionsWithContentSelector = ({ drive }) => { - console.log("DRIVEVV:", drive); const menuRef = useRef(); const toggleMenuRef = useRef(); const [isOpen, setIsOpen] = useState(false); const onToggle = () => setIsOpen(!isOpen); - const onDelete = () => { - console.log("DELETE CLICKED YAY"); - }; return ( { .filter((p) => p.mountPath) .map((partition) => { return ( - - } - actionId={`edit-${partition.mountPath}`} - aria-label={`Edit ${partition.mountPath}`} - /> - } - actionId={`delete-${partition.mountPath}`} - aria-label={`Delete ${partition.mountPath}`} - onClick={onDelete} - /> - - } - > - {partition.mountPath} - + driveName={drive.name} + mountPath={partition.mountPath} + /> ); })} diff --git a/web/src/queries/storage/config-model.ts b/web/src/queries/storage/config-model.ts index 0d0e27046d..93f18a1a3b 100644 --- a/web/src/queries/storage/config-model.ts +++ b/web/src/queries/storage/config-model.ts @@ -62,6 +62,18 @@ function isUsedDrive(model: configModel.Config, driveName: string) { return drive.partitions?.some((p) => isNewPartition(p) || isReusedPartition(p)); } +function findPartition( + model: configModel.Config, + driveName: string, + mountPath: string, +): configModel.Partition | undefined { + const drive = findDrive(model, driveName); + if (drive === undefined) return undefined; + + const partitions = drive.partitions || []; + return partitions.find((p) => p.mountPath === mountPath); +} + function isBoot(model: configModel.Config, driveName: string): boolean { return model.boot?.configure && driveName === model.boot?.device?.name; } @@ -104,6 +116,20 @@ function disableBoot(originalModel: configModel.Config): configModel.Config { return setBoot(originalModel, { configure: false }); } +function deletePartition( + originalModel: configModel.Config, + driveName: string, + mountPath: string, +): configModel.Config { + const model = copyModel(originalModel); + const drive = findDrive(model, driveName); + if (drive === undefined) return; + + const partitions = (drive.partitions || []).filter((p) => p.mountPath !== mountPath); + drive.partitions = partitions; + return model; +} + function switchDrive( originalModel: configModel.Config, driveName: string, @@ -252,6 +278,23 @@ export function useBoot(): BootHook { }; } +export type PartitionHook = { + onDelete: () => void; +}; + +// driveName, like "/dev/sda" +// mountPath, like "/" or "swap" +export function usePartition(driveName: string, mountPath: string): PartitionHook | undefined { + const model = useConfigModel(); + const { mutate } = useConfigModelMutation(); + + if (findPartition(model, driveName, mountPath) === undefined) return; + + return { + onDelete: () => mutate(deletePartition(model, driveName, mountPath)), + }; +} + export type DriveHook = { isBoot: boolean; isExplicitBoot: boolean;