diff --git a/web/src/client/software.js b/web/src/client/software.js index bb3157fdc6..22457a7b0d 100644 --- a/web/src/client/software.js +++ b/web/src/client/software.js @@ -126,7 +126,11 @@ class BaseProductManager { const email = proxy.Email; const requirement = this.registrationRequirement(proxy.Requirement); - return (code.length === 0 ? null : { code, email, requirement }); + const registration = { code, email, requirement }; + if (code.length === 0) registration.code = null; + if (email.length === 0) registration.email = null; + + return registration; } /** diff --git a/web/src/components/overview/ProductSection.jsx b/web/src/components/overview/ProductSection.jsx index 8b95d792af..2cdc700912 100644 --- a/web/src/components/overview/ProductSection.jsx +++ b/web/src/components/overview/ProductSection.jsx @@ -24,7 +24,7 @@ import { Text } from "@patternfly/react-core"; import { useCancellablePromise } from "~/utils"; import { useInstallerClient } from "~/context/installer"; import { useProduct } from "~/context/product"; -import { Section, SectionSkeleton } from "~/components/core"; +import { If, Section, SectionSkeleton } from "~/components/core"; import { _ } from "~/i18n"; const errorsFrom = (issues) => { @@ -44,12 +44,16 @@ export default function ProductSection() { }, [cancellablePromise, setIssues, software]); const Content = ({ isLoading = false }) => { - if (isLoading) return ; - return ( - - {selectedProduct?.name} - + } + else={ + + {selectedProduct?.name} + + } + /> ); }; @@ -64,7 +68,7 @@ export default function ProductSection() { icon="inventory_2" errors={errors} loading={isLoading} - path="/products" + path="/product" > diff --git a/web/src/components/overview/SoftwareSection.jsx b/web/src/components/overview/SoftwareSection.jsx index fd9867e5e1..7c31fd72b1 100644 --- a/web/src/components/overview/SoftwareSection.jsx +++ b/web/src/components/overview/SoftwareSection.jsx @@ -78,10 +78,6 @@ export default function SoftwareSection({ showErrors }) { return client.onStatusChange(updateStatus); }, [client, cancellablePromise]); - useEffect(() => { - cancellablePromise(client.getStatus()).then(updateStatus); - }, [client, cancellablePromise]); - useEffect(() => { const updateProposal = async () => { const errors = await cancellablePromise(client.getIssues()); diff --git a/web/src/components/product/ProductPage.jsx b/web/src/components/product/ProductPage.jsx new file mode 100644 index 0000000000..5385053f1a --- /dev/null +++ b/web/src/components/product/ProductPage.jsx @@ -0,0 +1,167 @@ +/* + * 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, useState } from "react"; +import { Button } from "@patternfly/react-core"; + +import { _ } from "~/i18n"; +import { BUSY } from "~/client/status"; +import { If, Page, Popup, Section } from "~/components/core"; +import { noop, useCancellablePromise } from "~/utils"; +import { ProductSelectionForm } from "~/components/product"; +import { useInstallerClient } from "~/context/installer"; +import { useProduct } from "~/context/product"; + +const ProductSelectionPopup = ({ isOpen = false, onAccept = noop, onCancel = noop }) => { + const { manager, software } = useInstallerClient(); + const { selectedProduct } = useProduct(); + + const onSubmit = async (id) => { + if (id !== selectedProduct?.id) { + await software.product.select(id); + manager.startProbing(); + } + + onAccept(); + }; + + return ( + + + + + {_("Accept")} + + + + + ); +}; + +const WithoutRegistrationButtons = ({ isDisabled = false }) => { + const [isPopupOpen, setIsPopupOpen] = useState(false); + + return ( + <> + + setIsPopupOpen(false)} + onCancel={() => setIsPopupOpen(false)} + /> + + ); +}; + +const DeregisteredButtons = ({ isDisabled = false }) => { + const [isSelectionPopupOpen, setIsSelectionPopupOpen] = useState(false); + + return ( + <> + + + setIsSelectionPopupOpen(false)} + onCancel={() => setIsSelectionPopupOpen(false)} + /> + + ); +}; + +const RegisteredButtons = ({ isDisabled = false }) => { + return ( + <> + + + + ); +}; + +const Buttons = ({ isDisabled = false }) => { + const { registration } = useProduct(); + + const withRegistration = registration.requirement !== "not-required"; + const registered = registration.code !== null; + + return ( + <> +
+ } + else={} + /> + } + else={} + /> +
+ {_("Configuring product. Actions are disabled until the product is configured.")}

+ } + /> + + ); +}; + +export default function ProductPage() { + const [status, setStatus] = useState(); + const { cancellablePromise } = useCancellablePromise(); + const { manager } = useInstallerClient(); + const { selectedProduct: product } = useProduct(); + + useEffect(() => { + cancellablePromise(manager.getStatus()).then(setStatus); + return manager.onStatusChange(setStatus); + }, [cancellablePromise, manager]); + + const isLoading = status === BUSY; + + return ( + +
+

{product.description}

+ +
+
+ ); +} diff --git a/web/src/components/product/index.js b/web/src/components/product/index.js index e3bd2cbde7..be414bd374 100644 --- a/web/src/components/product/index.js +++ b/web/src/components/product/index.js @@ -19,5 +19,6 @@ * find current contact information at www.suse.com. */ +export { default as ProductPage } from "./ProductPage"; export { default as ProductSelectionForm } from "./ProductSelectionForm"; export { default as ProductSelectionPage } from "./ProductSelectionPage"; diff --git a/web/src/index.js b/web/src/index.js index f47f5a76b5..53d58610a3 100644 --- a/web/src/index.js +++ b/web/src/index.js @@ -37,7 +37,7 @@ import App from "~/App"; import Main from "~/Main"; import DevServerWrapper from "~/DevServerWrapper"; import { Overview } from "~/components/overview"; -import { ProductSelectionPage } from "~/components/product"; +import { ProductPage, ProductSelectionPage } from "~/components/product"; import { SoftwarePage } from "~/components/software"; import { ProposalPage as StoragePage, ISCSIPage, DASDPage, ZFCPPage } from "~/components/storage"; import { UsersPage } from "~/components/users"; @@ -77,6 +77,7 @@ root.render( }> } /> } /> + } /> } /> } /> } />