Skip to content

Commit

Permalink
fix(web): allow reloading the page during installation (#1503)
Browse files Browse the repository at this point in the history
The new `useProduct` hook uses the Suspense API to display a "loading"
message while retrieving the
list of products. Unfortunately, that's a problem during installation:
the software service won't
response with the list of products and the UI will get stuck.

This PR fixes the problem by adding a `suspense` option `useProduct` so
you can decide when to use
the Suspense API.
  • Loading branch information
imobachgs committed Jul 26, 2024
2 parents cb36d47 + 00fb2da commit 7f55213
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 7 deletions.
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 @@
-------------------------------------------------------------------
Fri Jul 26 11:42:05 UTC 2024 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

- Allow reloading the page during installation
(gh#openSUSE/agama#1503).

-------------------------------------------------------------------
Mon Jul 22 15:28:42 UTC 2024 - Josef Reidinger <jreidinger@suse.com>

Expand Down
4 changes: 2 additions & 2 deletions web/src/MainLayout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import { rootRoutes } from "~/router";
import { useProduct } from "./queries/software";

const Header = () => {
const { selectedProduct } = useProduct();
const { selectedProduct } = useProduct({ suspense: true });
// NOTE: Agama is a name, do not translate
const title = selectedProduct?.name || _("Agama");

Expand Down Expand Up @@ -84,7 +84,7 @@ const Header = () => {

const ChangeProductButton = () => {
const navigate = useNavigate();
const { products } = useProduct();
const { products } = useProduct({ suspense: true });

if (!products.length) return null;

Expand Down
2 changes: 1 addition & 1 deletion web/src/components/product/ProductSelectionPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const Label = ({ children }) => (
);

function ProductSelectionPage() {
const { products, selectedProduct } = useProduct();
const { products, selectedProduct } = useProduct({ suspense: true });
const setConfig = useConfigMutation();
const [nextProduct, setNextProduct] = useState(selectedProduct);
const [isLoading, setIsLoading] = useState(false);
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/product/ProductSelectionProgress.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { useInstallerClient } from "~/context/installer";
* Shows progress steps when a product is selected.
*/
function ProductSelectionProgress() {
const { selectedProduct } = useProduct();
const { selectedProduct } = useProduct({ suspense: true });
const { manager } = useInstallerClient();
const [status, setStatus] = useState();

Expand Down
2 changes: 1 addition & 1 deletion web/src/components/storage/ProposalTransactionalInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { isTransactionalSystem } from "~/components/storage/utils";
* @param {ProposalSettings} props.settings - Settings used for calculating a proposal.
*/
export default function ProposalTransactionalInfo({ settings }) {
const { selectedProduct } = useProduct();
const { selectedProduct } = useProduct({ suspense: true });

if (!isTransactionalSystem(settings?.volumes)) return;

Expand Down
15 changes: 13 additions & 2 deletions web/src/queries/software.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import React from "react";
import {
useMutation,
useQueries,
useQueryClient,
useSuspenseQueries,
useSuspenseQuery,
Expand Down Expand Up @@ -116,11 +117,21 @@ const useConfigMutation = () => {
/**
* Returns available products and selected one, if any
*/
const useProduct = (): { products: Product[]; selectedProduct: Product | undefined } => {
const [{ data: selected }, { data: products }] = useSuspenseQueries({
const useProduct = (
options?: QueryHookOptions,
): { products?: Product[]; selectedProduct?: Product } => {
const func = options?.suspense ? useSuspenseQueries : useQueries;
const [
{ data: selected, isPending: isSelectedPending },
{ data: products, isPending: isProductsPending },
] = func({
queries: [selectedProductQuery(), productsQuery()],
});

if (isSelectedPending || isProductsPending) {
return {};
}

const selectedProduct = products.find((p: Product) => p.id === selected);
return {
products,
Expand Down
27 changes: 27 additions & 0 deletions web/src/types/queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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 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.
*/

/**
* Typical options for our queries hooks.
*/
type QueryHookOptions = {
suspense?: boolean;
};

0 comments on commit 7f55213

Please sign in to comment.