diff --git a/web/src/assets/styles/index.scss b/web/src/assets/styles/index.scss
index 8cdb560b93..cc12cc87e8 100644
--- a/web/src/assets/styles/index.scss
+++ b/web/src/assets/styles/index.scss
@@ -367,6 +367,7 @@ label.pf-m-disabled + .pf-v6-c-check__description {
.pf-v6-c-check {
row-gap: var(--pf-t--global--spacer--xs);
+ align-content: baseline;
input[type="checkbox"] {
align-self: center;
diff --git a/web/src/components/storage/ConfigEditorMenu.test.tsx b/web/src/components/storage/ConfigEditorMenu.test.tsx
index d28568b246..c5df5080c3 100644
--- a/web/src/components/storage/ConfigEditorMenu.test.tsx
+++ b/web/src/components/storage/ConfigEditorMenu.test.tsx
@@ -53,7 +53,7 @@ beforeEach(() => {
async function openMenu() {
const { user } = plainRender();
- const button = screen.getByRole("button", { name: "More options toggle" });
+ const button = screen.getByRole("button", { name: "Other options toggle" });
await user.click(button);
const menu = screen.getByRole("menu");
return { user, menu };
@@ -61,7 +61,7 @@ async function openMenu() {
it("renders the menu", () => {
plainRender();
- expect(screen.queryByText("More options")).toBeInTheDocument();
+ expect(screen.queryByText("Other options")).toBeInTheDocument();
});
it("allows users to change the boot options", async () => {
diff --git a/web/src/components/storage/ConfigEditorMenu.tsx b/web/src/components/storage/ConfigEditorMenu.tsx
index a03b263cdc..91c3e8c4b3 100644
--- a/web/src/components/storage/ConfigEditorMenu.tsx
+++ b/web/src/components/storage/ConfigEditorMenu.tsx
@@ -54,10 +54,10 @@ export default function ConfigEditorMenu() {
- {_("More options")}
+ {_("Other options")}
)}
>
diff --git a/web/src/components/storage/ConfigureDeviceMenu.test.tsx b/web/src/components/storage/ConfigureDeviceMenu.test.tsx
index 5d532e2c70..ec9d3e4a64 100644
--- a/web/src/components/storage/ConfigureDeviceMenu.test.tsx
+++ b/web/src/components/storage/ConfigureDeviceMenu.test.tsx
@@ -87,7 +87,7 @@ describe("ConfigureDeviceMenu", () => {
it("renders an initially closed menu ", async () => {
const { user } = plainRender();
- const toggler = screen.getByRole("button", { name: "Configure a device", expanded: false });
+ const toggler = screen.getByRole("button", { name: "More devices", expanded: false });
expect(screen.queryAllByRole("menu").length).toBe(0);
await user.click(toggler);
expect(toggler).toHaveAttribute("aria-expanded", "true");
@@ -96,7 +96,7 @@ describe("ConfigureDeviceMenu", () => {
it("allows users to add a new LVM volume group", async () => {
const { user } = plainRender();
- const toggler = screen.getByRole("button", { name: "Configure a device", expanded: false });
+ const toggler = screen.getByRole("button", { name: "More devices", expanded: false });
await user.click(toggler);
const lvmMenuItem = screen.getByRole("menuitem", { name: /LVM/ });
await user.click(lvmMenuItem);
@@ -107,7 +107,7 @@ describe("ConfigureDeviceMenu", () => {
describe("and no disks have been configured yet", () => {
it("allows users to add a new drive", async () => {
const { user } = plainRender();
- const toggler = screen.getByRole("button", { name: /Configure a device/ });
+ const toggler = screen.getByRole("button", { name: /More devices/ });
await user.click(toggler);
const disksMenuItem = screen.getByRole("menuitem", { name: /disk to define/ });
await user.click(disksMenuItem);
@@ -124,7 +124,7 @@ describe("ConfigureDeviceMenu", () => {
it("allows users to add a new drive to an unused disk", async () => {
const { user } = plainRender();
- const toggler = screen.getByRole("button", { name: /Configure a device/ });
+ const toggler = screen.getByRole("button", { name: /More devices/ });
await user.click(toggler);
const disksMenuItem = screen.getByRole("menuitem", { name: /disk to define/ });
await user.click(disksMenuItem);
@@ -143,7 +143,7 @@ describe("ConfigureDeviceMenu", () => {
it("renders the disks menu as disabled with an informative label", async () => {
const { user } = plainRender();
- const toggler = screen.getByRole("button", { name: /Configure a device/ });
+ const toggler = screen.getByRole("button", { name: /More devices/ });
await user.click(toggler);
const disksMenuItem = screen.getByRole("menuitem", { name: /disk to define/ });
expect(disksMenuItem).toBeDisabled();
diff --git a/web/src/components/storage/ConfigureDeviceMenu.tsx b/web/src/components/storage/ConfigureDeviceMenu.tsx
index dafb5586cd..17b43e77d9 100644
--- a/web/src/components/storage/ConfigureDeviceMenu.tsx
+++ b/web/src/components/storage/ConfigureDeviceMenu.tsx
@@ -63,17 +63,20 @@ const DisksDrillDownMenuItem = ({
}: DisksDrillDownMenuItemProps) => {
const isDisabled = !devices.length;
- const disabledDescription = _("Already using all availalbe disks.");
+ const disabledDescription = _("Already using all available disks");
const enabledDescription = drivesCount
? sprintf(
n_(
- "Extends the installation beyond the currently selected disk",
- "Extends the installation beyond the current %d disks",
+ "Extend the installation beyond the currently selected disk",
+ "Extend the installation beyond the current %d disks",
drivesCount,
),
drivesCount,
)
- : _("Extends the installation using a disk");
+ : _("Start configuring a basic installation");
+ const title = drivesCount
+ ? _("Select another disk to define partitions")
+ : _("Select a disk to define partitions");
return (
);
};
@@ -194,6 +193,10 @@ export default function ConfigureDeviceMenu() {
}
};
+ const lvmDescription = allDevices.length
+ ? _("Define a new LVM on top of one or several disks")
+ : _("Define a new LVM on the disk");
+
return (
- {_("Configure a device")}
+ {_("More devices")}
}
menuRef={menuRef}
@@ -228,7 +231,7 @@ export default function ConfigureDeviceMenu() {
diff --git a/web/src/components/storage/DriveEditor.tsx b/web/src/components/storage/DriveEditor.tsx
index f6ee7af4fa..20d526fbe1 100644
--- a/web/src/components/storage/DriveEditor.tsx
+++ b/web/src/components/storage/DriveEditor.tsx
@@ -447,7 +447,7 @@ const DriveHeader = ({ drive, driveDevice }: DriveEditorProps) => {
if (isBoot) {
// TRANSLATORS: %s will be replaced by the device name and its size - "/dev/sda, 20 GiB"
- return _("Use %s to boot");
+ return _("Use %s to configure boot partitions");
}
// TRANSLATORS: %s will be replaced by the device name and its size - "/dev/sda, 20 GiB"
return _("Use %s");
diff --git a/web/src/components/storage/ProposalFailedInfo.tsx b/web/src/components/storage/ProposalFailedInfo.tsx
index b5af24c369..41b8c1e37e 100644
--- a/web/src/components/storage/ProposalFailedInfo.tsx
+++ b/web/src/components/storage/ProposalFailedInfo.tsx
@@ -29,7 +29,7 @@ import { IssueSeverity } from "~/types/issues";
import * as partitionUtils from "~/components/storage/utils/partition";
import { sprintf } from "sprintf-js";
-function Description({ partitions }) {
+function Description({ partitions, booting }) {
const newPartitions = partitions.filter((p) => !p.name);
if (!newPartitions.length) {
@@ -43,17 +43,29 @@ function Description({ partitions }) {
}
const mountPaths = newPartitions.map((p) => partitionUtils.pathWithSize(p));
- const msg1 = sprintf(
- // TRANSLATORS: %s is a list of formatted mount points with a partition size like
- // '"/" (at least 10 GiB), "/var" (20 GiB) and "swap" (2 GiB)'
- // (or a single mount point in the singular case).
- n_(
- "It is not possible to allocate the requested partition for %s.",
- "It is not possible to allocate the requested partitions for %s.",
- mountPaths.length,
- ),
- formatList(mountPaths),
- );
+ const msg1 = booting
+ ? sprintf(
+ // TRANSLATORS: %s is a list of formatted mount points with a partition size like
+ // '"/" (at least 10 GiB), "/var" (20 GiB) and "swap" (2 GiB)'
+ // (or a single mount point in the singular case).
+ n_(
+ "It is not possible to allocate the requested partitions for booting and for %s.",
+ "It is not possible to allocate the requested partitions for booting, %s.",
+ mountPaths.length,
+ ),
+ formatList(mountPaths),
+ )
+ : sprintf(
+ // TRANSLATORS: %s is a list of formatted mount points with a partition size like
+ // '"/" (at least 10 GiB), "/var" (20 GiB) and "swap" (2 GiB)'
+ // (or a single mount point in the singular case).
+ n_(
+ "It is not possible to allocate the requested partition for %s.",
+ "It is not possible to allocate the requested partitions for %s.",
+ mountPaths.length,
+ ),
+ formatList(mountPaths),
+ );
return (
<>
@@ -78,10 +90,11 @@ export default function ProposalFailedInfo() {
if (!errors.length) return;
const modelPartitions = model.drives.flatMap((d) => d.partitions || []);
+ const booting = !!model.boot?.configure;
return (
-
+
);
}
diff --git a/web/src/components/storage/ProposalPage.tsx b/web/src/components/storage/ProposalPage.tsx
index f1eae52f59..353abc0a2f 100644
--- a/web/src/components/storage/ProposalPage.tsx
+++ b/web/src/components/storage/ProposalPage.tsx
@@ -237,7 +237,7 @@ export default function ProposalPage(): React.ReactNode {
if (isDeprecated) reprobe().catch(console.log);
}, [isDeprecated, reprobe]);
- const fixable = ["no_root", "required_filesystems"];
+ const fixable = ["no_root", "required_filesystems", "vg_target_devices"];
const unfixableErrors = configErrors.filter((e) => !fixable.includes(e.kind));
const isModelEditable = model && !unfixableErrors.length;
const hasDevices = !!availableDevices.length;