-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(web): move installation issues to a drawer and keep Install butt…
…on always visible (#1778) ## Problem [A month ago](#1690) , the 'Install' button achieved more visibility after being moved to the sticky header, allowing users to access it from any page/section/screen. But that was just an intermediate step towards improving the 'Install' action and the discoverability of 'Installation setup problems,' which sadly introduced some drawbacks: * The Install button is displayed dynamically, which still _forces_ users to figure out where it will appear when it’s not visible from the start. * When installation is not possible, users have to navigate to the Overview page to see what is making their setup invalid. ## Solution * Keep the install button always enabled and visible, triggering the installation when the setup is valid or displaying found _issues_ when not, and * Allow users to check found problems always, not only in the overview ## A discarded alternative At commit 6ecdceb, this set of changes was in a bit different shape, where the interface rendered a disabled "Install" button and an enabled "Warning" button to display the setup problems. Additionally, it featured a _tooltip_ to explain to users why the "Install" button was disabled and where to click to view the reasons in detail. However, this approach created unnecessary complexity and moving pieces, not to mention the challenge of writing a clear, concise, yet complete explanation for the _tooltip_ and keeping it up-to-date, including translations What's more, there is no reason to avoid keeping the "Install" button **always active but behaving slightly different** depending on the setup status: * Displaying found problems when the installation setup is invalid * Displaying the confirmation dialog when the setup is valid This way, the user doesn't need to think. They can simply click the "Install" button. If it's not possible, they can immediately start fixing their setup. If it is possible, they just have to confirm they want to begin the installation. --- Related to not yet planned Trello card, https://trello.com/c/DmUOQN1Y (internal link)
- Loading branch information
Showing
16 changed files
with
378 additions
and
328 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,10 @@ | ||
------------------------------------------------------------------- | ||
Mon Nov 25 11:12:36 UTC 2024 - David Diaz <[email protected]> | ||
|
||
- Unify Install and "warning" header buttons. | ||
- Move installation issues to a drawer shown when Install button | ||
is clicked (gh#agama-project#agama#1778). | ||
|
||
------------------------------------------------------------------- | ||
Fri Nov 15 16:48:44 UTC 2024 - Ladislav Slezák <[email protected]> | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/* | ||
* 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 the GNU General Public License as published by the Free | ||
* Software Foundation; either version 2 of the License, or (at your option) | ||
* any later version. | ||
* | ||
* 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. | ||
*/ | ||
|
||
import React from "react"; | ||
import { screen, within } from "@testing-library/react"; | ||
import { installerRender } from "~/test-utils"; | ||
import { InstallationPhase } from "~/types/status"; | ||
import { IssuesList } from "~/types/issues"; | ||
import IssuesDrawer from "./IssuesDrawer"; | ||
|
||
let phase = InstallationPhase.Config; | ||
let mockIssuesList: IssuesList; | ||
const onCloseFn = jest.fn(); | ||
|
||
jest.mock("~/queries/issues", () => ({ | ||
...jest.requireActual("~/queries/issues"), | ||
useAllIssues: () => mockIssuesList, | ||
})); | ||
|
||
jest.mock("~/queries/status", () => ({ | ||
useInstallerStatus: () => ({ | ||
phase, | ||
}), | ||
})); | ||
|
||
const itRendersNothing = () => | ||
it("renders nothing", () => { | ||
const { container } = installerRender(<IssuesDrawer onClose={onCloseFn} />); | ||
expect(container).toBeEmptyDOMElement(); | ||
}); | ||
|
||
describe("IssuesDrawer", () => { | ||
describe("when there are no installation issues", () => { | ||
beforeEach(() => { | ||
mockIssuesList = new IssuesList([], [], [], []); | ||
}); | ||
|
||
itRendersNothing(); | ||
}); | ||
|
||
describe("when there are installation issues", () => { | ||
beforeEach(() => { | ||
mockIssuesList = new IssuesList( | ||
[], | ||
[ | ||
{ | ||
description: "Software Fake Issue", | ||
source: 0, | ||
severity: 0, | ||
details: "Software Fake Issue details", | ||
}, | ||
], | ||
[ | ||
{ | ||
description: "Storage Fake Issue 1", | ||
source: 0, | ||
severity: 0, | ||
details: "Storage Fake Issue 1 details", | ||
}, | ||
{ | ||
description: "Storage Fake Issue 2", | ||
source: 0, | ||
severity: 0, | ||
details: "Storage Fake Issue 2 details", | ||
}, | ||
], | ||
[ | ||
{ | ||
description: "Users Fake Issue", | ||
source: 0, | ||
severity: 0, | ||
details: "Users Fake Issue details", | ||
}, | ||
], | ||
); | ||
}); | ||
|
||
it("renders the drawer with categorized issues linking to their scope", async () => { | ||
const { user } = installerRender(<IssuesDrawer onClose={onCloseFn} />); | ||
|
||
const softwareIssues = screen.getByRole("region", { name: "Software" }); | ||
const storageIssues = screen.getByRole("region", { name: "Storage" }); | ||
const usersIssues = screen.getByRole("region", { name: "Users" }); | ||
|
||
const softwareLink = within(softwareIssues).getByRole("link", { name: "Software" }); | ||
expect(softwareLink).toHaveAttribute("href", "/software"); | ||
within(softwareIssues).getByText("Software Fake Issue"); | ||
|
||
const storageLink = within(storageIssues).getByRole("link", { name: "Storage" }); | ||
expect(storageLink).toHaveAttribute("href", "/storage"); | ||
within(storageIssues).getByText("Storage Fake Issue 1"); | ||
within(storageIssues).getByText("Storage Fake Issue 2"); | ||
|
||
const usersLink = within(usersIssues).getByRole("link", { name: "Users" }); | ||
expect(usersLink).toHaveAttribute("href", "/users"); | ||
within(usersIssues).getByText("Users Fake Issue"); | ||
|
||
const closeButton = screen.getByRole("button", { name: "Close" }); | ||
await user.click(closeButton); | ||
expect(onCloseFn).toHaveBeenCalled(); | ||
}); | ||
|
||
describe("at install phase", () => { | ||
beforeEach(() => { | ||
phase = InstallationPhase.Install; | ||
}); | ||
|
||
itRendersNothing(); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.