diff --git a/ui/webui/src/components/AnacondaAboutModal.jsx b/ui/webui/src/components/AnacondaAboutModal.jsx
new file mode 100644
index 000000000000..278d6177fc0a
--- /dev/null
+++ b/ui/webui/src/components/AnacondaAboutModal.jsx
@@ -0,0 +1,90 @@
+/*
+ * 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 .
+ */
+import cockpit from "cockpit";
+
+import React, { useState, useEffect } from "react";
+import {
+ AboutModal,
+ Button,
+ Flex,
+ TextContent,
+ TextList,
+ TextListItem,
+} 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";
+
+const _ = cockpit.gettext;
+
+const AboutModalVersions = ({ anacondaVersion }) => {
+ const arr = [["Anaconda", anacondaVersion], ["Blivet", "XXX"], ["Pykickstart", "XXX"], ["Python", "XXX"]];
+
+ return (
+ <>
+
+
{_("Powered by Anaconda")}
+
+
+
+
+ {arr.map((item) => (
+
+ {item[0]}
+ {item[1]}
+
+ ))}
+
+
+ >
+ );
+};
+
+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 (
+ <>
+
+
+
+ }>
+ Anaconda project page
+
+ }>
+ Report a bug
+
+
+
+ >
+ );
+};
diff --git a/ui/webui/src/components/AnacondaHeader.jsx b/ui/webui/src/components/AnacondaHeader.jsx
index 5d900bc8f233..8361d5bfb9a9 100644
--- a/ui/webui/src/components/AnacondaHeader.jsx
+++ b/ui/webui/src/components/AnacondaHeader.jsx
@@ -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;
@@ -66,6 +67,7 @@ export const AnacondaHeader = ({ beta, title }) => {
{title}
{betanag}
+
);
diff --git a/ui/webui/src/components/HeaderKebab.jsx b/ui/webui/src/components/HeaderKebab.jsx
new file mode 100644
index 000000000000..593f581e1ed5
--- /dev/null
+++ b/ui/webui/src/components/HeaderKebab.jsx
@@ -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 .
+ */
+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 = [
+
+ About
+ ,
+ ];
+ return (
+ <>
+
+ }
+ isOpen={isOpen}
+ isPlain
+ dropdownItems={dropdownItems}
+ />
+ {isAboutModalOpen &&
+ }
+ >
+
+ );
+};
diff --git a/ui/webui/src/components/aboutmodal.scss b/ui/webui/src/components/aboutmodal.scss
new file mode 100644
index 000000000000..1e107e569564
--- /dev/null
+++ b/ui/webui/src/components/aboutmodal.scss
@@ -0,0 +1,53 @@
+@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);
+ }
+
+ #about-modal-flex{
+ position: static;
+ margin-top: 10rem;
+ }
+
+ .pf-c-about-modal-box__content {
+ margin-top: 0;
+ }
+
+ #anaconda-page-button {
+ padding-left: 0;
+ }
+
+ #subtitle {
+ margin-bottom: 48px;
+ }
+
+ #about-modal-content {
+ font-size: large;
+ }
+
+
\ No newline at end of file
diff --git a/ui/webui/src/helpers/product.js b/ui/webui/src/helpers/product.js
new file mode 100644
index 000000000000..101aed4d696e
--- /dev/null
+++ b/ui/webui/src/helpers/product.js
@@ -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 .
+ */
+import cockpit from "cockpit";
+
+export const getAnacondaVersion = () => {
+ return cockpit.spawn(["anaconda", "--version"])
+ .then(content => content.split(" ").slice(-1)[0].replace("\n", ""))
+ .then(content => { return content });
+};
diff --git a/ui/webui/src/index.js b/ui/webui/src/index.js
index 18cafa5aa3e4..0c2e645ea031 100644
--- a/ui/webui/src/index.js
+++ b/ui/webui/src/index.js
@@ -32,6 +32,7 @@ import cockpit from "cockpit";
*/
import "../pkg/lib/patternfly/patternfly-4-overrides.scss";
import "./components/app.scss";
+import "./components/aboutmodal.scss";
document.addEventListener("DOMContentLoaded", function () {
const root = createRoot(document.getElementById("app"));