diff --git a/web/package/cockpit-agama.changes b/web/package/cockpit-agama.changes index c30f451d63..261e3b7e5f 100644 --- a/web/package/cockpit-agama.changes +++ b/web/package/cockpit-agama.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Thu Oct 26 16:07:02 UTC 2023 - Imobach Gonzalez Sosa + +- Properly track the status changes. It prevents of getting stuck + in the first page when there are multiple products + (gh#openSUSE/agama#821). + ------------------------------------------------------------------- Thu Oct 26 05:58:15 UTC 2023 - Imobach Gonzalez Sosa diff --git a/web/src/App.jsx b/web/src/App.jsx index e9bc359cc5..50e09eedff 100644 --- a/web/src/App.jsx +++ b/web/src/App.jsx @@ -34,7 +34,6 @@ import { Disclosure, Installation, IssuesLink, - LoadingEnvironment, LogsButton, ShowLogButton, ShowTerminalButton, @@ -63,6 +62,18 @@ function App() { const [status, setStatus] = useState(undefined); const [phase, setPhase] = useState(undefined); + useEffect(() => { + if (client) { + return client.manager.onPhaseChange(setPhase); + } + }, [client, setPhase]); + + useEffect(() => { + if (client) { + return client.manager.onStatusChange(setStatus); + } + }, [client, setStatus]); + useEffect(() => { const loadPhase = async () => { const phase = await client.manager.getPhase(); @@ -71,14 +82,10 @@ function App() { setStatus(status); }; - if (client) loadPhase().catch(console.error); - }, [client, setPhase, setStatus]); - - useEffect(() => { if (client) { - return client.manager.onPhaseChange(setPhase); + loadPhase().catch(console.error); } - }, [client, setPhase]); + }, [client, setPhase, setStatus]); const Content = () => { if (!client || !products) { @@ -86,7 +93,7 @@ function App() { } if ((phase === STARTUP && status === BUSY) || phase === undefined || status === undefined) { - return ; + return ; } if (phase === INSTALL) { diff --git a/web/src/App.test.jsx b/web/src/App.test.jsx index f63ea46cff..84092633b6 100644 --- a/web/src/App.test.jsx +++ b/web/src/App.test.jsx @@ -44,7 +44,6 @@ jest.mock("~/context/software", () => ({ // Mock some components, // See https://www.chakshunyu.com/blog/how-to-mock-a-react-component-in-jest/#default-export jest.mock("~/components/core/DBusError", () =>
D-BusError Mock
); -jest.mock("~/components/core/LoadingEnvironment", () => () =>
LoadingEnvironment Mock
); jest.mock("~/components/questions/Questions", () => () =>
Questions Mock
); jest.mock("~/components/core/Installation", () => () =>
Installation Mock
); jest.mock("~/components/core/Sidebar", () => () =>
Sidebar Mock
); @@ -56,6 +55,7 @@ const getPhaseFn = jest.fn(); // capture the latest subscription to the manager#onPhaseChange for triggering it manually const onPhaseChangeFn = cb => { callbacks.onPhaseChange = cb }; +const onStatusChangeFn = cb => { callbacks.onStatusChange = cb }; const changePhaseTo = phase => act(() => callbacks.onPhaseChange(phase)); describe("App", () => { @@ -68,6 +68,7 @@ describe("App", () => { getStatus: getStatusFn, getPhase: getPhaseFn, onPhaseChange: onPhaseChangeFn, + onStatusChange: onStatusChangeFn, }, language: { getUILanguage: jest.fn().mockResolvedValue("en-us"), @@ -92,7 +93,7 @@ describe("App", () => { mockProducts = undefined; }); - it("renders the LoadingEnvironment screen", async () => { + it("renders the Loading screen", async () => { installerRender(, { withL10n: true }); await screen.findByText(/Loading installation environment/); }); @@ -104,9 +105,9 @@ describe("App", () => { getStatusFn.mockResolvedValue(BUSY); }); - it("renders the LoadingEnvironment screen", async () => { + it("renders the Loading screen", async () => { installerRender(, { withL10n: true }); - await screen.findByText("LoadingEnvironment Mock"); + await screen.findByText(/Loading installation environment/); }); }); @@ -116,10 +117,10 @@ describe("App", () => { getStatusFn.mockResolvedValue(BUSY); }); - it("renders the LoadingEnvironment component", async () => { + it("renders the Loading screen", async () => { installerRender(, { withL10n: true }); - await screen.findByText("LoadingEnvironment Mock"); + await screen.findByText(/Loading installation environment/); }); }); diff --git a/web/src/components/core/LoadingEnvironment.jsx b/web/src/components/core/LoadingEnvironment.jsx deleted file mode 100644 index b5d20b203e..0000000000 --- a/web/src/components/core/LoadingEnvironment.jsx +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) [2023] 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. - */ - -import React, { useEffect } from "react"; -import { Loading } from "~/components/layout"; -import { useInstallerClient } from "~/context/installer"; - -/** - * Loading indicator for a phase - * - * @component - * - * @param {function} onStatusChange callback triggered when the status changes - */ -function LoadingEnvironment({ onStatusChange }) { - const client = useInstallerClient(); - - useEffect(() => - client.manager.onStatusChange(onStatusChange), [client.manager, onStatusChange] - ); - - return ; -} - -export default LoadingEnvironment; diff --git a/web/src/components/core/index.js b/web/src/components/core/index.js index a1500a3317..d457f49889 100644 --- a/web/src/components/core/index.js +++ b/web/src/components/core/index.js @@ -38,7 +38,6 @@ export { default as InstallButton } from "./InstallButton"; export { default as IssuesLink } from "./IssuesLink"; export { default as IssuesPage } from "./IssuesPage"; export { default as SectionSkeleton } from "./SectionSkeleton"; -export { default as LoadingEnvironment } from "./LoadingEnvironment"; export { default as LogsButton } from "./LogsButton"; export { default as FileViewer } from "./FileViewer"; export { default as RowActions } from "./RowActions";