Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 2 additions & 2 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ function App() {
return <Navigate to={ROOT.installationFinished} />;
}

if (!products || !connected) return <Loading useLayout />;
if (!products || !connected) return <Loading listenQuestions />;

if (phase === InstallationPhase.Startup && isBusy) {
return <Loading useLayout />;
return <Loading listenQuestions />;
}

if (selectedProduct === undefined && location.pathname !== PRODUCT.root) {
Expand Down
46 changes: 17 additions & 29 deletions web/src/components/core/ProgressReport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,19 @@

import React, { useEffect, useState } from "react";
import {
Bullseye,
Card,
CardBody,
Content,
Flex,
Grid,
GridItem,
ProgressStep,
ProgressStepper,
ProgressStepProps,
Spinner,
Stack,
Truncate,
} from "@patternfly/react-core";

import { _ } from "~/i18n";
import { useProgress, useProgressChanges, useResetProgress } from "~/queries/progress";
import { Progress as ProgressType } from "~/types/progress";
import sizingStyles from "@patternfly/react-styles/css/utilities/Sizing/sizing";
import { _ } from "~/i18n";

type StepProps = {
id: string;
Expand Down Expand Up @@ -90,7 +85,10 @@ const Progress = ({ steps, step, firstStep, detail }) => {
};

return (
<ProgressStepper isCenterAligned className="progress-report">
<ProgressStepper
isCenterAligned
className={[sizingStyles.w_100, sizingStyles.h_33OnMd].join(" ")}
>
{firstStep && (
<ProgressStep key="initial" variant="success">
{firstStep}
Expand Down Expand Up @@ -132,27 +130,17 @@ function ProgressReport({ title, firstStep }: { title: string; firstStep?: React
const detail = findDetail([softwareProgress, storageProgress]);

return (
<Bullseye>
<Grid hasGutter>
<GridItem sm={10} smOffset={1}>
<Card isPlain>
<CardBody>
<Flex
direction={{ default: "column" }}
rowGap={{ default: "rowGap2xl" }}
alignItems={{ default: "alignItemsCenter" }}
>
<Spinner size="xl" />
<Content component="h1" id="progress-title" style={{ textAlign: "center" }}>
{title}
</Content>
<Progress steps={steps} step={progress} detail={detail} firstStep={firstStep} />
</Flex>
</CardBody>
</Card>
</GridItem>
</Grid>
</Bullseye>
<Flex
direction={{ default: "column" }}
rowGap={{ default: "rowGapMd" }}
alignItems={{ default: "alignItemsCenter" }}
justifyContent={{ default: "justifyContentCenter" }}
className={sizingStyles.h_100OnMd}
>
<Spinner size="xl" />
<Content component="h1">{title}</Content>
<Progress steps={steps} step={progress} detail={detail} firstStep={firstStep} />
</Flex>
);
}

Expand Down
8 changes: 4 additions & 4 deletions web/src/components/layout/Loading.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,18 @@ describe("Loading", () => {
});
});

describe("when not using the useLayout prop or its value is false", () => {
describe("when not using the listenQuestions prop or it's set to false", () => {
it("does not wrap the content within a PlainLayout", () => {
const { rerender } = plainRender(<Loading text="Making a test" />);
expect(screen.queryByText("PlainLayout Mock")).toBeNull();
rerender(<Loading text="Making a test" useLayout={false} />);
rerender(<Loading text="Making a test" listenQuestions={false} />);
expect(screen.queryByText("PlainLayout Mock")).toBeNull();
});
});

describe("when using the useLayout prop", () => {
describe("when using the listenQuestions prop", () => {
it("wraps the content within a PlainLayout with neither, header nor sidebar", () => {
installerRender(<Loading text="Making a test" useLayout />);
installerRender(<Loading text="Making a test" listenQuestions />);
expect(screen.queryByText("Header Mock")).toBeNull();
expect(screen.queryByText("Sidebar Mock")).toBeNull();
screen.getByText("PlainLayout Mock");
Expand Down
40 changes: 32 additions & 8 deletions web/src/components/layout/Loading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
* find current contact information at www.suse.com.
*/

import React from "react";
import { Bullseye, EmptyState, Spinner } from "@patternfly/react-core";
import React, { Fragment } from "react";
import { EmptyState, Spinner } from "@patternfly/react-core";
import { PlainLayout } from "~/components/layout";
import { LayoutProps } from "~/components/layout/Layout";
import { _ } from "~/i18n";
Expand All @@ -31,16 +31,40 @@ const Layout = (props: LayoutProps) => (
<PlainLayout mountHeader={false} mountSidebar={false} {...props} />
);

type LoadingProps = {
/** Text to be rendered alongside the spinner */
text?: string;
/**
* Whether the loading screen should listen for and render any questions
*
* The Questions component is mounted within the application layout
* (src/components/Layout.tsx). However, certain branches in src/App.tsx force
* to render the Loading component before the layout is mounted.
*
* This behavior requires a mechanism to enable the loading to listen
* for and render backend questions before the frontend has all the
* data necessary to fully mount the layout.
*
* This is why this prop exists. While this could be improved and ideally
* the Loading component shouldn’t need to wrap itself with the layout, be
* cautious when tempted to remove this behavior without a solid alternative.
* Doing so could silently reintroduced the regression fixed in
* https://github.com/agama-project/agama/pull/1825
*
* FIXME: Find and implement a solid alternative
*/
listenQuestions?: boolean;
};

function Loading({
text = _("Loading installation environment, please wait."),
useLayout = false,
}) {
const Wrapper = useLayout ? Layout : React.Fragment;
listenQuestions = false,
}: LoadingProps) {
const Wrapper = listenQuestions ? Layout : Fragment;

return (
<Wrapper>
<Bullseye>
<EmptyState variant="xl" titleText={text} headingLevel="h1" icon={LoadingIcon} />
</Bullseye>
<EmptyState variant="xl" titleText={text} headingLevel="h1" icon={LoadingIcon} />
</Wrapper>
);
}
Expand Down