Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Oct 27, 2023
1 parent a1ef542 commit 9b89562
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 13 deletions.
6 changes: 5 additions & 1 deletion web/src/client/software.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand Down
18 changes: 11 additions & 7 deletions web/src/components/overview/ProductSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -44,12 +44,16 @@ export default function ProductSection() {
}, [cancellablePromise, setIssues, software]);

const Content = ({ isLoading = false }) => {
if (isLoading) return <SectionSkeleton numRows={1} />;

return (
<Text>
{selectedProduct?.name}
</Text>
<If
condition={isLoading}
then={<SectionSkeleton numRows={1} />}
else={
<Text>
{selectedProduct?.name}
</Text>
}
/>
);
};

Expand All @@ -64,7 +68,7 @@ export default function ProductSection() {
icon="inventory_2"
errors={errors}
loading={isLoading}
path="/products"
path="/product"
>
<Content isLoading={isLoading} />
</Section>
Expand Down
4 changes: 0 additions & 4 deletions web/src/components/overview/SoftwareSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
178 changes: 178 additions & 0 deletions web/src/components/product/ProductPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* 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 UserNotDefined = ({ actionCb }) => {
// return (
// <div className="stack">
// <div className="bold">{_("No user defined yet")}</div>
// <div>{_("Please, be aware that a user must be defined before installing the system to be able to log into it.")}</div>
// {/* TRANSLATORS: push button label */}
// <Button variant="primary" onClick={actionCb}>{_("Define a user now")}</Button>
// </div>
// );
// };

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 (
<Popup
title={_("Choose a product")}
description=""
isOpen={isOpen}
>
<ProductSelectionForm id="productSelectionForm" onSubmit={onSubmit} />
<Popup.Actions>
<Popup.Confirm form="productSelectionForm" type="submit">
{_("Accept")}
</Popup.Confirm>
<Popup.Cancel onClick={onCancel} />
</Popup.Actions>
</Popup>
);
};

const WithoutRegistrationButtons = ({ isDisabled = false }) => {
const [isPopupOpen, setIsPopupOpen] = useState(false);

return (
<>
<Button
variant="primary"
onClick={() => setIsPopupOpen(true)}
isDisabled={isDisabled}
>
{_("Change product")}
</Button>
<ProductSelectionPopup
isOpen={isPopupOpen}
onAccept={() => setIsPopupOpen(false)}
onCancel={() => setIsPopupOpen(false)}
/>
</>
);
};

const DeregisteredButtons = ({ isDisabled = false }) => {
const [isSelectionPopupOpen, setIsSelectionPopupOpen] = useState(false);

return (
<>
<Button variant="primary" isDisabled={isDisabled}>{_("Register")}</Button>
<Button
variant="secondary"
onClick={() => setIsSelectionPopupOpen(true)}
isDisabled={isDisabled}
>
{_("Change product")}
</Button>
<ProductSelectionPopup
isOpen={isSelectionPopupOpen}
onAccept={() => setIsSelectionPopupOpen(false)}
onCancel={() => setIsSelectionPopupOpen(false)}
/>
</>
);
};

const RegisteredButtons = ({ isDisabled = false }) => {
return (
<>
<Button variant="primary" isDisabled={isDisabled}>{_("Deregister")}</Button>
<Button variant="secondary" isDisabled={isDisabled}>{_("Change product")}</Button>
</>
);
};

const Buttons = ({ isDisabled = false }) => {
const { registration } = useProduct();

const withRegistration = registration.requirement !== "not-required";
const registered = registration.code !== null;

return (
<>
<div className="split">
<If
condition={withRegistration}
then={
<If
condition={registered}
then={<RegisteredButtons isDisabled={isDisabled} />}
else={<DeregisteredButtons isDisabled={isDisabled} />}
/>
}
else={<WithoutRegistrationButtons isDisabled={isDisabled} />}
/>
</div>
<If
condition={isDisabled}
then={
<p>{_("Configuring product. Actions are disabled until the product is configured.")}</p>
}
/>
</>
);
};

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 (
<Page title={_("Product")} icon="inventory_2" actionLabel={_("Back")} actionVariant="secondary">
<Section title={product.name} loading={isLoading}>
<p>{product.description}</p>
<Buttons isDisabled={isLoading} />
</Section>
</Page>
);
}
1 change: 1 addition & 0 deletions web/src/components/product/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
3 changes: 2 additions & 1 deletion web/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -77,6 +77,7 @@ root.render(
<Route path="/" element={<Main />}>
<Route index element={<Overview />} />
<Route path="/overview" element={<Overview />} />
<Route path="/product" element={<ProductPage />} />
<Route path="/l10n" element={<L10nPage />} />
<Route path="/software" element={<SoftwarePage />} />
<Route path="/storage" element={<StoragePage />} />
Expand Down

0 comments on commit 9b89562

Please sign in to comment.