Skip to content

Commit

Permalink
webui: provide an About screen
Browse files Browse the repository at this point in the history
  • Loading branch information
acruzgon committed Jul 13, 2023
1 parent 0e04108 commit 12fd2f3
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 0 deletions.
102 changes: 102 additions & 0 deletions ui/webui/src/components/AnacondaAboutModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2023 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with This program; If not, see <http://www.gnu.org/licenses/>.
*/
import cockpit from "cockpit";

import React, { useState, useEffect } from "react";
import {
AboutModal,
Button,
Flex,
TextContent,
TextList,
TextListItem,
Stack,
StackItem
} from "@patternfly/react-core";
import { ExternalLinkAltIcon } from "@patternfly/react-icons";

import { read_os_release as readOsRelease } from "os-release.js";
import { getAnacondaVersion } from "../helpers/product.js";

const _ = cockpit.gettext;

const AboutModalVersions = ({ anacondaVersion }) => {
const arr = [["Anaconda", anacondaVersion]];

return (
<TextContent>
<TextList id="about-modal-content" component="dl">
{arr.map((item) => (
<React.Fragment key={item[0]}>
<TextListItem component="dt">{item[0]}</TextListItem>
<TextListItem component="dd">{item[1]}</TextListItem>
</React.Fragment>
))}
</TextList>
</TextContent>
);
};

const ProductName = ({ prettyName }) => {
return (
<Stack hasGutter>
<StackItem>{prettyName}</StackItem>
<StackItem className="subtitle">{_("Powered by Anaconda")}</StackItem>
</Stack>
);
};

export const AnacondaAboutModal = ({ isModalOpen, setIsAboutModalOpen }) => {
const toggleModal = () => {
setIsAboutModalOpen(!isModalOpen);
};

const [anacondaVersion, setAnacondaVersion] = useState("");
const [prettyName, setPrettyName] = useState("");
useEffect(() => {
getAnacondaVersion().then(content => setAnacondaVersion(content));
readOsRelease().then(osRelease => setPrettyName(osRelease.PRETTY_NAME));
}, []);

return (
<>
<AboutModal
noAboutModalBoxContentContainer
isOpen={isModalOpen}
onClose={toggleModal}
trademark="Anaconda © 2023 Red Hat, Inc."
productName={<ProductName prettyName={prettyName} />}
>
<Flex id="about-modal-flex2" direction={{ default: "column" }} justifyContent={{ default: "justifyContentSpaceBetween" }}>
<AboutModalVersions anacondaVersion={anacondaVersion} />
<Flex id="about-modal-flex">
<Button
isInline
id="anaconda-page-button"
variant="link"
icon={<ExternalLinkAltIcon />}
href="https://github.com/rhinstaller/anaconda"
target="_blank"
component="a">
{_("Anaconda project page")}
</Button>
</Flex>
</Flex>
</AboutModal>
</>
);
};
48 changes: 48 additions & 0 deletions ui/webui/src/components/AnacondaAboutModal.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@import "global-variables";

.pf-c-about-modal-box__strapline {
padding-top: 0;
}

/* Scale down the about box to be a little smaller */
@media only screen and (min-width: 992px) {
.pf-c-about-modal-box {
--pf-c-about-modal-box--lg--MaxWidth: 62rem;
--pf-c-about-modal-box--lg--MaxHeight: 38rem;
grid-template-rows: 3rem max-content auto;
grid-template-columns: 1fr 0fr;
}
}

/* Hide the logo and side graphic */
.pf-c-about-modal-box__brand,
.pf-c-about-modal-box__hero {
display: none;
}

/* Make the close button more obvious, since we hide the side graphic*/
.pf-c-about-modal-box__close .pf-c-button.pf-m-plain {
--pf-c-about-modal-box__close--c-button--BackgroundColor: var(--pf-global--BackgroundColor--dark-200);
position: absolute;
}
.pf-c-about-modal-box__close .pf-c-button.pf-m-plain:hover {
--pf-c-about-modal-box__close--c-button--BackgroundColor: var(--pf-global--BackgroundColor--dark-400);
}

.pf-c-about-modal-box {
.subtitle {
font-size: var(--pf-c-title--m-2xl--FontSize);
}

.pf-c-about-modal-box__body {
height: 100%;

> .pf-l-flex {
height: 100%;
}

#about-modal-content {
font-size: large;
}
}
}
2 changes: 2 additions & 0 deletions ui/webui/src/components/AnacondaHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
TextContent, Text, TextVariants
} from "@patternfly/react-core";
import { InfoCircleIcon } from "@patternfly/react-icons";
import { HeaderKebab } from "./HeaderKebab";

const _ = cockpit.gettext;

Expand Down Expand Up @@ -66,6 +67,7 @@ export const AnacondaHeader = ({ beta, title }) => {
<Text component="h1">{title}</Text>
</TextContent>
{betanag}
<HeaderKebab />
</Flex>
</PageSection>
);
Expand Down
69 changes: 69 additions & 0 deletions ui/webui/src/components/HeaderKebab.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2023 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with This program; If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useState } from "react";
import { Dropdown, DropdownItem, DropdownPosition, KebabToggle } from "@patternfly/react-core";
import { AnacondaAboutModal } from "./AnacondaAboutModal";

export const HeaderKebab = () => {
const [isOpen, setIsOpen] = useState(false);
const [isAboutModalOpen, setIsAboutModalOpen] = useState(false);

const onToggle = isOpen => {
setIsOpen(isOpen);
};
const onFocus = () => {
const element = document.getElementById("toggle-kebab");
element.focus();
};
const onSelect = () => {
setIsOpen(false);
onFocus();
};

const handleAboutModal = () => {
setIsAboutModalOpen(true);
};

const dropdownItems = [
<DropdownItem key="separated link" onClick={handleAboutModal}>
About
</DropdownItem>,
];
return (
<>
<Dropdown
position={DropdownPosition.right}
onSelect={onSelect}
toggle={
<KebabToggle
id="toggle-kebab"
onToggle={onToggle}
/>
}
isOpen={isOpen}
isPlain
dropdownItems={dropdownItems}
/>
{isAboutModalOpen &&
<AnacondaAboutModal
isModalOpen={isAboutModalOpen}
setIsAboutModalOpen={setIsAboutModalOpen}
/>}
</>

);
};
23 changes: 23 additions & 0 deletions ui/webui/src/helpers/product.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2023 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with This program; If not, see <http://www.gnu.org/licenses/>.
*/
import cockpit from "cockpit";

export const getAnacondaVersion = () => {
return cockpit
.spawn(["anaconda", "--version"])
.then((content) => content.split(" ").slice(-1)[0].replace("\n", ""));
};
1 change: 1 addition & 0 deletions ui/webui/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import cockpit from "cockpit";
*/
import "../pkg/lib/patternfly/patternfly-4-overrides.scss";
import "./components/app.scss";
import "./components/AnacondaAboutModal.scss";

document.addEventListener("DOMContentLoaded", function () {
const root = createRoot(document.getElementById("app"));
Expand Down

0 comments on commit 12fd2f3

Please sign in to comment.