Skip to content

Commit

Permalink
Added a new About modal in the UI (#3933)
Browse files Browse the repository at this point in the history
* Added a new About modal in the UI (and revamped the masthead).

* Refactored the auth components
  • Loading branch information
EricWittmann authored Nov 3, 2023
1 parent 1d5cad2 commit 6ac5800
Show file tree
Hide file tree
Showing 18 changed files with 187 additions and 77 deletions.
7 changes: 7 additions & 0 deletions ui/.scripts/generate-version.cjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
#! /usr/bin/env node
var shell = require("shelljs");
const fs = require("fs");
const packageJson = require('../package.json');

console.info("-------------------------------------------------------");
console.info("Getting current git SHA");
const gitSHA = shell.exec("git rev-parse HEAD", { silent: true }).stdout.trim();
console.info(` SHA: ${gitSHA}`);
console.info("-------------------------------------------------------");

console.info("-------------------------------------------------------");
console.info("Generating version.js");
Expand All @@ -14,6 +20,7 @@ const VERSION_OUTPUT_PATH="./ui-app/dist/version.js";
const info = {
name: "Apicurio Registry",
version: packageJson.version,
digest: gitSHA,
builtOn: new Date(),
url: "https://www.apicur.io/registry/"
};
Expand Down
4 changes: 2 additions & 2 deletions ui/ui-app/config/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ var ApicurioInfo = {
name: "Apicurio Registry",
version: "DEV",
digest: "DEV",
builtOn: new Date(),
url: "http://www.apicur.io/"
builtOn: new Date().toString(),
url: "http://www.apicur.io/registry"
};
2 changes: 2 additions & 0 deletions ui/ui-app/public/apicurio_registry_icon_reverse.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { FunctionComponent } from "react";
import { Services } from "@services/services";
import { Services } from "@services/services.ts";
import { AuthService } from "@services/auth";

/**
Expand Down
1 change: 1 addition & 0 deletions ui/ui-app/src/app/components/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./ApplicationAuth.tsx";
export * from "./IfAuth.tsx";
1 change: 0 additions & 1 deletion ui/ui-app/src/app/components/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export * from "./ArtifactTypeIcon.tsx";
export * from "./If.tsx";
export * from "./IfAuth.tsx";
export * from "./IfFeature.tsx";
export * from "./IfNotEmpty.tsx";
export * from "./UrlUpload.tsx";
Expand Down
42 changes: 42 additions & 0 deletions ui/ui-app/src/app/components/header/AppAboutModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { FunctionComponent } from "react";
import { AboutModal, TextContent, TextList, TextListItem } from "@patternfly/react-core";
import { VersionType } from "@services/version";
import { Services } from "@services/services.ts";


export type AppAboutModalProps = {
isOpen: boolean;
onClose: () => void;
};


export const AppAboutModal: FunctionComponent<AppAboutModalProps> = (props: AppAboutModalProps) => {
const version: VersionType = Services.getVersionService().getVersion();

return (
<AboutModal
isOpen={props.isOpen}
onClose={props.onClose}
trademark="&copy; 2024 Red Hat"
brandImageSrc="/apicurio_registry_icon_reverse.svg"
brandImageAlt={version.name}
productName={version.name}
>
<TextContent>
<TextList component="dl">
<TextListItem component="dt">Project</TextListItem>
<TextListItem component="dd"><a href={version.url} target="_blank">{ version.name }</a></TextListItem>

<TextListItem component="dt">Version</TextListItem>
<TextListItem component="dd">{ version.version }</TextListItem>

<TextListItem component="dt">Built on</TextListItem>
<TextListItem component="dd">{ "" + version.builtOn }</TextListItem>

<TextListItem component="dt">Digest</TextListItem>
<TextListItem component="dd">{ version.digest }</TextListItem>
</TextList>
</TextContent>
</AboutModal>
);
};
8 changes: 0 additions & 8 deletions ui/ui-app/src/app/components/header/AppHeader.css

This file was deleted.

47 changes: 14 additions & 33 deletions ui/ui-app/src/app/components/header/AppHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import React, { FunctionComponent } from "react";
import "./AppHeader.css";
import { AvatarDropdown, IfAuth } from "@app/components";
import {
PageHeader,
PageHeaderTools,
PageHeaderToolsGroup,
PageHeaderToolsItem
} from "@patternfly/react-core/deprecated";
import { FunctionComponent } from "react";
import { Brand, Masthead, MastheadBrand, MastheadContent, MastheadMain } from "@patternfly/react-core";
import { AppNavigation, useAppNavigation } from "@hooks/useAppNavigation.ts";
import { Link } from "react-router-dom";
import { AppHeaderToolbar } from "@app/components";


export type AppHeaderProps = {
Expand All @@ -18,30 +13,16 @@ export type AppHeaderProps = {
export const AppHeader: FunctionComponent<AppHeaderProps> = () => {
const appNavigation: AppNavigation = useAppNavigation();

const logoProps = {
href: appNavigation.createLink("/")
};

const logo: React.ReactNode = (
<div className="app-logo">
<img className="pf-c-brand logo-make" src="/apicurio_registry_logo_reverse.svg" alt="Apicurio Registry"/>
</div>
);

const headerActions: React.ReactElement = (
<PageHeaderTools className="header-toolbar">
<PageHeaderToolsGroup>
<PageHeaderToolsItem id="avatar">
<IfAuth enabled={true}>
<AvatarDropdown />
</IfAuth>
</PageHeaderToolsItem>
</PageHeaderToolsGroup>
</PageHeaderTools>
);

return (
<PageHeader logo={logo} logoProps={logoProps} showNavToggle={false} headerTools={headerActions} />
<Masthead id="icon-router-link">
<MastheadMain>
<MastheadBrand component={props => <Link {...props} to={ appNavigation.createLink("/artifacts") } />}>
<Brand src="/apicurio_registry_logo_reverse.svg" alt="Apicurio Registry" heights={{ default: "36px" }} />
</MastheadBrand>
</MastheadMain>
<MastheadContent>
<AppHeaderToolbar />
</MastheadContent>
</Masthead>
);

};
38 changes: 38 additions & 0 deletions ui/ui-app/src/app/components/header/AppHeaderToolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FunctionComponent, useState } from "react";
import { Button, Toolbar, ToolbarContent, ToolbarGroup, ToolbarItem } from "@patternfly/react-core";
import { QuestionCircleIcon } from "@patternfly/react-icons";
import { AvatarDropdown, IfAuth } from "@app/components";
import { AppAboutModal } from "@app/components/header/AppAboutModal.tsx";


export type AppHeaderToolbarProps = {
// No properties.
};


export const AppHeaderToolbar: FunctionComponent<AppHeaderToolbarProps> = () => {
const [isAboutModalOpen, setIsAboutModalOpen] = useState(false);

return (
<>
<AppAboutModal isOpen={isAboutModalOpen} onClose={() => setIsAboutModalOpen(false)} />
<Toolbar id="app-header-toolbar" isFullHeight={true}>
<ToolbarContent>
<ToolbarGroup align={{ default: "alignRight" }}>
<ToolbarItem>
<Button variant="plain" onClick={() => setIsAboutModalOpen(!isAboutModalOpen)}>
<QuestionCircleIcon style={{ fontSize: "16px" }} />
</Button>
</ToolbarItem>
<ToolbarItem>
<IfAuth enabled={true}>
<AvatarDropdown />
</IfAuth>
</ToolbarItem>
</ToolbarGroup>
</ToolbarContent>
</Toolbar>
</>
);

};
15 changes: 0 additions & 15 deletions ui/ui-app/src/app/components/header/AvatarDropdown.css

This file was deleted.

25 changes: 10 additions & 15 deletions ui/ui-app/src/app/components/header/AvatarDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import React, { FunctionComponent, useState } from "react";
import "./AvatarDropdown.css";
import {
Avatar,
Dropdown,
DropdownItem,
DropdownList,
MenuToggle,
MenuToggleElement
} from "@patternfly/react-core";
import { Avatar, Dropdown, DropdownItem, DropdownList, MenuToggle, MenuToggleElement } from "@patternfly/react-core";
import { Services } from "@services/services.ts";


Expand All @@ -27,23 +19,26 @@ export const AvatarDropdown: FunctionComponent<AvatarDropdownProps> = () => {
setIsOpen(!isOpen);
};

const icon = (
<Avatar src="/avatar.png" alt="User" />
);

return (
<Dropdown
isOpen={isOpen}
onSelect={onSelect}
onOpenChange={(isOpen: boolean) => setIsOpen(isOpen)}
popperProps={{
position: "right"
}}
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle
ref={toggleRef}
aria-label="kebab dropdown toggle"
variant="plain"
onClick={onToggle}
isFullHeight={true}
isExpanded={isOpen}
icon={icon}
>
<Avatar src="/avatar.png" alt="User" />
{
Services.getUsersService().currentUser().displayName || "User"
}
</MenuToggle>
)}
shouldFocusToggleOnSelect
Expand Down
5 changes: 3 additions & 2 deletions ui/ui-app/src/app/components/header/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./AvatarDropdown";
export * from "./AppHeader.tsx";
export * from "./RootPageHeader.tsx";
export * from "./AppHeader";
export * from "./AppHeaderToolbar";
export * from "./RootPageHeader";
1 change: 1 addition & 0 deletions ui/ui-app/src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from "./logger";
export * from "./services";
export * from "./users";
export * from "./url";
export * from "./version";
6 changes: 6 additions & 0 deletions ui/ui-app/src/services/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DownloaderService } from "./downloader";
import { AuthService } from "./auth";
import { UsersService } from "./users";
import { AlertsService } from "./alerts";
import { VersionService } from "@services/version";

// TODO convert all of the services into React hooks

Expand All @@ -25,6 +26,10 @@ export class Services {
return Services.all.config;
}

public static getVersionService(): VersionService {
return Services.all.version;
}

public static getDownloaderService(): DownloaderService {
return Services.all.downloader;
}
Expand Down Expand Up @@ -53,6 +58,7 @@ export class Services {
groups: new GroupsService(),
users: new UsersService(),
config: new ConfigService(),
version: new VersionService(),
downloader: new DownloaderService(),
admin: new AdminService(),
logger: new LoggerService(),
Expand Down
2 changes: 2 additions & 0 deletions ui/ui-app/src/services/version/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./version.service.ts";
export * from "./version.type.ts";
50 changes: 50 additions & 0 deletions ui/ui-app/src/services/version/version.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { VersionType } from "@services/version/version.type.ts";
import { Service } from "@services/baseService.ts";

const DEFAULT_VERSION: VersionType = {
name: "Apicurio Registry",
version: "DEV",
digest: "DEV",
builtOn: new Date().toString(),
url: "http://www.apicur.io/"
};


export function getVersion(): VersionType {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (ApicurioInfo) { return ApicurioInfo as VersionType; }

const gw: any = window as any;
if (gw["ApicurioInfo"]) {
return gw["ApicurioInfo"] as VersionType;
}

return DEFAULT_VERSION;
}


/**
* A simple configuration service. Reads information from a global "ApicurioRegistryConfig" variable
* that is typically included via JSONP.
*/
export class VersionService implements Service {
private version: VersionType;

constructor() {
this.version = getVersion();
}

public init(): void {
// Nothing to init (done in c'tor)
}

public updateConfig(version: VersionType): void {
this.version = version;
}

public getVersion(): VersionType {
return this.version;
}

}
8 changes: 8 additions & 0 deletions ui/ui-app/src/services/version/version.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

export interface VersionType {
name: string;
version: string;
digest: string;
builtOn: string;
url: string;
}

0 comments on commit 6ac5800

Please sign in to comment.