From f145f01fe430e733a23b0500fdd55f3c9754556e Mon Sep 17 00:00:00 2001 From: Ancor Gonzalez Sosa Date: Wed, 26 Mar 2025 21:51:49 +0000 Subject: [PATCH 1/4] web: Align grids of multi-line checkboxes --- web/src/assets/styles/index.scss | 1 + 1 file changed, 1 insertion(+) 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; From 53e05e8065ff936bd635395c55d843fd11f3d810 Mon Sep 17 00:00:00 2001 From: Ancor Gonzalez Sosa Date: Wed, 26 Mar 2025 21:52:50 +0000 Subject: [PATCH 2/4] web: Handle more recoverable errors --- web/src/components/storage/ProposalPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 86888427597aad1ca1fc17d388a1ad7db1ce90ec Mon Sep 17 00:00:00 2001 From: Ancor Gonzalez Sosa Date: Wed, 26 Mar 2025 23:16:20 +0000 Subject: [PATCH 3/4] web: Reword some ConfigEditor buttons --- .../storage/ConfigEditorMenu.test.tsx | 4 +-- .../components/storage/ConfigEditorMenu.tsx | 4 +-- .../storage/ConfigureDeviceMenu.test.tsx | 10 ++++---- .../storage/ConfigureDeviceMenu.tsx | 25 +++++++++++-------- 4 files changed, 23 insertions(+), 20 deletions(-) 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 ( } > - {n_( - "Select another disk to define partitions", - "Select a disk to define partitions", - drivesCount, - )} + {title} ); }; @@ -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() { navigate(PATHS.volumeGroup.add)} - description={_("Extend the installation using LVM")} + description={lvmDescription} > {_("Add LVM volume group")} From 7cc76e233ea6099b5b69be27d2fb5e57326f7b76 Mon Sep 17 00:00:00 2001 From: Ancor Gonzalez Sosa Date: Thu, 27 Mar 2025 07:36:48 +0000 Subject: [PATCH 4/4] web: Clarify wording about boot partitions --- web/src/components/storage/DriveEditor.tsx | 2 +- .../components/storage/ProposalFailedInfo.tsx | 39 ++++++++++++------- 2 files changed, 27 insertions(+), 14 deletions(-) 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 ( - + ); }