diff --git a/web/src/components/storage/ProposalSettingsSection.jsx b/web/src/components/storage/ProposalSettingsSection.jsx
index 3ae852af7b..57e10656d3 100644
--- a/web/src/components/storage/ProposalSettingsSection.jsx
+++ b/web/src/components/storage/ProposalSettingsSection.jsx
@@ -25,8 +25,9 @@ import React, { useEffect, useState } from "react";
import { Button, Checkbox, Form, Skeleton, Switch, Tooltip } from "@patternfly/react-core";
import { sprintf } from "sprintf-js";
-import { _, n_ } from "~/i18n";
-import { BootSelectionDialog, ProposalVolumes, SpacePolicyDialog } from "~/components/storage";
+import { _ } from "~/i18n";
+import { BootSelectionDialog, ProposalVolumes } from "~/components/storage";
+import SpacePolicyField from "~/components/storage/SpacePolicyField";
import { If, PasswordAndConfirmationInput, Section, Popup } from "~/components/core";
import { Icon } from "~/components/layout";
import { noop } from "~/utils";
@@ -337,72 +338,6 @@ const BootConfigField = ({
);
};
-/**
- * Allows to select the space policy.
- * @component
- *
- * @param {object} props
- * @param {SpacePolicy|undefined} props.policy
- * @param {SpaceAction[]} props.actions
- * @param {StorageDevice[]} props.devices
- * @param {boolean} props.isLoading
- * @param {(config: SpacePolicyConfig) => void} props.onChange
- *
- * @typedef {object} SpacePolicyConfig
- * @property {SpacePolicy} spacePolicy
- * @property {SpaceAction[]} spaceActions
- */
-const SpacePolicyField = ({
- policy,
- actions,
- devices,
- isLoading,
- onChange
-}) => {
- const [isDialogOpen, setIsDialogOpen] = useState(false);
-
- const openDialog = () => setIsDialogOpen(true);
-
- const closeDialog = () => setIsDialogOpen(false);
-
- const onAccept = ({ spacePolicy, spaceActions }) => {
- closeDialog();
- onChange({ spacePolicy, spaceActions });
- };
-
- const label = () => {
- // eslint-disable-next-line agama-i18n/string-literals
- if (policy.summaryLabels.length === 1) return _(policy.summaryLabels[0]);
-
- // eslint-disable-next-line agama-i18n/string-literals
- return sprintf(n_(policy.summaryLabels[0], policy.summaryLabels[1], devices.length), devices.length);
- };
-
- if (isLoading || !policy) {
- return ;
- }
-
- return (
-
- {_("Find space")}
-
-
- }
- />
-
- );
-};
-
/**
* Section for editing the proposal settings
* @component
diff --git a/web/src/components/storage/SpacePolicyField.jsx b/web/src/components/storage/SpacePolicyField.jsx
new file mode 100644
index 0000000000..a1bc41e64c
--- /dev/null
+++ b/web/src/components/storage/SpacePolicyField.jsx
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) [2024] SUSE LLC
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, contact SUSE LLC.
+ *
+ * To contact SUSE LLC about this file by physical or electronic mail, you may
+ * find current contact information at www.suse.com.
+ */
+
+// @ts-check
+
+import React, { useState } from "react";
+import { Skeleton } from "@patternfly/react-core";
+
+import { sprintf } from "sprintf-js";
+import { _, n_ } from "~/i18n";
+import { If, SettingsField } from "~/components/core";
+import SpacePolicyDialog from "~/components/storage/SpacePolicyDialog";
+
+/**
+ * @typedef {import ("~/client/storage").SpaceAction} SpaceAction
+ * @typedef {import ("~/components/storage/utils").SpacePolicy} SpacePolicy
+ * @typedef {import ("~/client/storage").StorageDevice} StorageDevice
+ *
+ * @typedef {object} SpacePolicyConfig
+ * @property {SpacePolicy} spacePolicy
+ * @property {SpaceAction[]} spaceActions
+ */
+
+/**
+ * Allows to select the space policy.
+ * @component
+ *
+ * @param {object} props
+ * @param {SpacePolicy|undefined} props.policy
+ * @param {SpaceAction[]} props.actions
+ * @param {StorageDevice[]} props.devices
+ * @param {boolean} props.isLoading
+ * @param {(config: SpacePolicyConfig) => void} props.onChange
+ *
+ */
+export default function SpacePolicyField({
+ policy,
+ actions,
+ devices,
+ isLoading,
+ onChange
+}) {
+ const [isDialogOpen, setIsDialogOpen] = useState(false);
+
+ const openDialog = () => setIsDialogOpen(true);
+
+ const closeDialog = () => setIsDialogOpen(false);
+
+ const onAccept = ({ spacePolicy, spaceActions }) => {
+ closeDialog();
+ onChange({ spacePolicy, spaceActions });
+ };
+
+ let value;
+ if (isLoading || !policy) {
+ value = ;
+ } else if (policy.summaryLabels.length === 1) {
+ // eslint-disable-next-line agama-i18n/string-literals
+ value = _(policy.summaryLabels[0]);
+ } else {
+ // eslint-disable-next-line agama-i18n/string-literals
+ value = sprintf(n_(policy.summaryLabels[0], policy.summaryLabels[1], devices.length), devices.length);
+ }
+
+ return (
+
+
+ }
+ />
+
+ );
+}
diff --git a/web/src/components/storage/utils.js b/web/src/components/storage/utils.js
index 6e45ad190c..1e842c211c 100644
--- a/web/src/components/storage/utils.js
+++ b/web/src/components/storage/utils.js
@@ -215,7 +215,7 @@ const deviceLabel = (device) => {
const deviceChildren = (device) => {
const partitionTableChildren = (partitionTable) => {
const { partitions, unusedSlots } = partitionTable;
- const children = partitions.concat(unusedSlots);
+ const children = partitions.concat(unusedSlots).filter(i => !!i);
return children.sort((a, b) => a.start < b.start ? -1 : 1);
};