Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions web/package/agama-web-ui.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Thu Jan 22 03:57:13 UTC 2026 - David Diaz <dgonzalez@suse.com>

- Updated top header install button label to clarify navigation to
the overview page (gh#agama-project/agama#3060).

-------------------------------------------------------------------
Wed Jan 21 10:48:33 UTC 2026 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@
import React from "react";
import { screen } from "@testing-library/react";
import { installerRender, mockRoutes } from "~/test-utils";
import { InstallButton } from "~/components/core";
import { PRODUCT, ROOT, STORAGE } from "~/routes/paths";
import ReviewAndInstallButton from "./ReviewAndInstallButton";

describe("InstallButton", () => {
describe("when not in an extended side paths", () => {
beforeEach(() => {
mockRoutes(STORAGE.addPartition);
});

it("renders the button with Install label ", () => {
installerRender(<InstallButton />);
screen.getByRole("button", { name: "Install" });
it("renders the button with 'Review and install' label ", () => {
installerRender(<ReviewAndInstallButton />);
screen.getByRole("button", { name: "Review and install" });
});
});

Expand All @@ -53,7 +53,7 @@ describe("InstallButton", () => {
});

it("renders nothing", () => {
const { container } = installerRender(<InstallButton />);
const { container } = installerRender(<ReviewAndInstallButton />);
expect(container).toBeEmptyDOMElement();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,29 @@
* find current contact information at www.suse.com.
*/

import React, { useId } from "react";
import React from "react";
import { Button, ButtonProps } from "@patternfly/react-core";
import { useLocation, useNavigate } from "react-router";
import { EXTENDED_SIDE_PATHS, ROOT } from "~/routes/paths";
import { _ } from "~/i18n";

/**
* A call-to-action button that navigates users to the overview page containing
* the actual installation button.
* A call-to-action button that directs users to the overview page, which
* contains the actual installation button.
*
* Despite its name, this component doesn't trigger installation directly.
* Instead, it serves as a prominent navigation element to guide users toward
* the overview page where the real installation button resides. The "Install"
* label is intentionally simple and action-oriented to match user intent.
* This button does not trigger installation directly. Instead, it serves as a
* navigation element that guides users to the overview page where they can
* review installation details before proceeding. The label "Review and Install"
* is intentional, indicating that users will first be presented with a summary
* screen before they can proceed with the installation.
*
* @todo Refactor component name and behavior
* - Rename to better reflect its navigation purpose
* @todo Refactor component behavior
* - Replace route-based visibility logic with explicit prop-based control now
* that pages manage their own layouts
*/
const InstallButton = (
export default function ReviewAndInstallButton(
props: Omit<ButtonProps, "onClick"> & { onClickWithIssues?: () => void },
) => {
const labelId = useId();
) {
const navigate = useNavigate();
const location = useLocation();

Expand All @@ -53,14 +52,12 @@ const InstallButton = (

const { onClickWithIssues, ...buttonProps } = props;

// TRANSLATORS: The install button label
const buttonText = _("Install");
// TRANSLATORS: The review and install button label
const buttonText = _("Review and install");

return (
<Button variant="primary" {...buttonProps} onClick={navigateToConfirmation}>
<span id={labelId}>{buttonText}</span>
<Button {...buttonProps} onClick={navigateToConfirmation}>
{buttonText}
</Button>
);
};

export default InstallButton;
}
2 changes: 1 addition & 1 deletion web/src/components/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export { default as EmailInput } from "./EmailInput";
export { default as InstallationFinished } from "./InstallationFinished";
export { default as InstallationProgress } from "./InstallationProgress";
export { default as InstallationExit } from "./InstallationExit";
export { default as InstallButton } from "./InstallButton";
export { default as ReviewAndInstallButton } from "./ReviewAndInstallButton";
export { default as IssuesAlert } from "./IssuesAlert";
export { default as ListSearch } from "./ListSearch";
export { default as LoginPage } from "./LoginPage";
Expand Down
6 changes: 4 additions & 2 deletions web/src/components/layout/Header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ const network: System = {
};

jest.mock("~/components/core/InstallerOptions", () => () => <div>Installer Options Mock</div>);
jest.mock("~/components/core/InstallButton", () => () => <div>Install Button Mock</div>);
jest.mock("~/components/core/ReviewAndInstallButton", () => () => (
<div>ReviewAndInstall Button Mock</div>
));

jest.mock("~/hooks/model/system", () => ({
...jest.requireActual("~/hooks/model/system"),
Expand Down Expand Up @@ -85,7 +87,7 @@ describe("Header", () => {

it("mounts the Install button", () => {
plainRender(<Header />);
screen.getByText("Install Button Mock");
screen.getByText("ReviewAndInstall Button Mock");
});

it("mounts installer options by default", () => {
Expand Down
9 changes: 7 additions & 2 deletions web/src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ import {
ToolbarItem,
} from "@patternfly/react-core";
import { Icon } from "~/components/layout";
import { ChangeProductOption, InstallerOptions, InstallButton, SkipTo } from "~/components/core";
import {
ChangeProductOption,
InstallerOptions,
ReviewAndInstallButton,
SkipTo,
} from "~/components/core";
import ProgressStatusMonitor from "~/components/core/ProgressStatusMonitor";
import Breadcrumbs from "~/components/core/Breadcrumbs";
import { useProductInfo } from "~/hooks/model/config/product";
Expand Down Expand Up @@ -166,7 +171,7 @@ export default function Header({
</ToolbarItem>
)}
<ToolbarItem>
<InstallButton />
<ReviewAndInstallButton />
</ToolbarItem>
<ToolbarItem>
<OptionsDropdown />
Expand Down