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 (
+
+ );
+};
+
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 (
-
+ 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;