Skip to content

Commit

Permalink
feat: add catalog/explorer chooser to "consortia pages" header (#2862)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fran McDade authored and Fran McDade committed Nov 14, 2023
1 parent c5a8489 commit 6b65163
Show file tree
Hide file tree
Showing 21 changed files with 1,104 additions and 358 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { Logo } from "@clevercanary/data-explorer-ui/lib/components/Layout/components/Header/components/Content/components/Logo/logo";
import { mediaTabletDown } from "@clevercanary/data-explorer-ui/lib/styles/common/mixins/breakpoints";
import styled from "@emotion/styled";

export const Brands = styled.div`
align-items: center;
display: flex;
flex-wrap: wrap;
gap: 8px 16px;
img {
margin: 0;
}
${mediaTabletDown} {
a {
padding-left: 0;
padding-right: 0;
}
}
`;

export const PortalLogo = styled(Logo)`
padding: 5px 8px;
${mediaTabletDown} {
flex-basis: 100%;
order: 1;
img {
height: 26px;
}
}
`;

export const NHGRILogo = styled(Logo)`
padding: 8px;
${mediaTabletDown} {
img {
height: 20px;
}
}
`;

export const NIHLogo = styled(Logo)`
padding: 8px;
${mediaTabletDown} {
img {
height: 20px;
}
}
`;

export const HHSLogo = styled(Logo)`
padding: 4px;
${mediaTabletDown} {
img {
height: 28px;
}
}
`;

export const USAGOVLogo = styled(Logo)`
padding: 4px;
${mediaTabletDown} {
img {
height: 28px;
}
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ANCHOR_TARGET } from "@clevercanary/data-explorer-ui/lib/components/Links/common/entities";
import {
Brands,
HHSLogo,
NHGRILogo,
NIHLogo,
PortalLogo,
USAGOVLogo,
} from "./anvilBranding.styles";

export interface ANVILBrandingProps {
portalURL?: string;
}

export const ANVILBranding = ({
portalURL,
}: ANVILBrandingProps): JSX.Element => {
return (
<Brands>
{portalURL && (
<PortalLogo
alt="AnVIL"
height={30}
link={portalURL}
src="/consortia/logos/anvilPortal.png"
target={ANCHOR_TARGET.BLANK}
/>
)}
<NHGRILogo
alt="NHGRI"
height={24}
link="https://www.genome.gov/"
src="/consortia/logos/nhgri.svg"
target={ANCHOR_TARGET.BLANK}
/>
<NIHLogo
alt="NIH"
height={24}
link="https://www.nih.gov/"
src="/consortia/logos/nih.svg"
target={ANCHOR_TARGET.BLANK}
/>
<HHSLogo
alt="HHS"
height={32}
link="https://www.hhs.gov/"
src="/consortia/logos/hhs.svg"
target={ANCHOR_TARGET.BLANK}
/>
<USAGOVLogo
alt="USA.GOV"
height={32}
link="https://www.usa.gov/"
src="/consortia/logos/usagov.png"
target={ANCHOR_TARGET.BLANK}
/>
</Brands>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import styled from "@emotion/styled";

export const Label = styled.div`
align-items: center;
display: flex;
gap: 4px;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { OpenInNewIcon } from "@clevercanary/data-explorer-ui/lib/components/common/CustomIcon/components/OpenInNewIcon/openInNewIcon";
import { ElementType } from "react";
import { Label } from "./labelIconMenuItem.styles";

export interface LabelIconMenuItemProps {
Icon?: ElementType;
iconFontSize?: string;
label: string;
}

export const LabelIconMenuItem = ({
Icon = OpenInNewIcon,
iconFontSize = "xsmall",
label,
}: LabelIconMenuItemProps): JSX.Element => {
return (
<Label>
<div>{label}</div>
<Icon color="inkLight" fontSize={iconFontSize} />
</Label>
);
};
50 changes: 50 additions & 0 deletions next/components/Layout/components/Header/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Header as DXHeader } from "@clevercanary/data-explorer-ui/lib/components/Layout/components/Header/header";
import { useMemo } from "react";
import { FEATURES } from "../../../../hooks/useFeatureFlag/common/entities";
import { useFeatureFlag } from "../../../../hooks/useFeatureFlag/useFeatureFlag";
import {
Header as HeaderProps,
NavLinkItem,
} from "../../../../site-config/common/entities";

export const Header = (headerProps: HeaderProps): JSX.Element => {
const isFeatureFlag = useFeatureFlag(FEATURES.HEADER);
const configuredHeaderProps = useMemo(
() => configureHeader(headerProps, isFeatureFlag),
[headerProps, isFeatureFlag]
);
return <DXHeader {...configuredHeaderProps} />;
};

/**
* Returns the header properties for the site config and feature flag.
* @param header - Site config header.
* @param isFeatureFlag - Flag indicating if feature is available to user.
* @returns header properties.
*/
function configureHeader(
header: HeaderProps,
isFeatureFlag: boolean
): HeaderProps {
const navLinks = filterFeatureFlagNavigation(header.navLinks, isFeatureFlag);
return {
...header,
navLinks,
};
}

/**
* Returns the header navigation links for the site config and feature flag.
* @param navLinks - Nav links.
* @param isFeatureFlag - Flag indicating if feature is available to user.
* @returns navigation links.
*/
function filterFeatureFlagNavigation(
navLinks: NavLinkItem[],
isFeatureFlag: boolean
): NavLinkItem[] {
return navLinks.filter(
({ featureFlag }) =>
featureFlag === undefined || featureFlag === isFeatureFlag
);
}
3 changes: 3 additions & 0 deletions next/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export { Grid } from "@clevercanary/data-explorer-ui/lib/components/common/Grid/
export { StaticImage } from "@clevercanary/data-explorer-ui/lib/components/common/StaticImage/staticImage";
export { AppLayout } from "@clevercanary/data-explorer-ui/lib/components/Layout/components/AppLayout/appLayout.styles";
export { Footer } from "@clevercanary/data-explorer-ui/lib/components/Layout/components/Footer/footer";
export { Logo } from "@clevercanary/data-explorer-ui/lib/components/Layout/components/Header/components/Content/components/Logo/logo";
export { Header } from "@clevercanary/data-explorer-ui/lib/components/Layout/components/Header/header";
export { Main } from "@clevercanary/data-explorer-ui/lib/components/Layout/components/Main/main.styles";
export { NavBarHero } from "@clevercanary/data-explorer-ui/lib/components/Layout/components/Nav/components/NavBarHero/navBarHero";
Expand All @@ -22,3 +23,5 @@ export { Resources } from "../components/Consortia/CSER/components/Resources/res
export { Figure } from "./common/Figure/figure";
export { NonBreakingSpace as NBS } from "./common/Typography/components/NonBreakingSpace/nonBreakingSpace";
export { TextBodyLarge500 } from "./common/Typography/components/TextBodyLarge500/textBodyLarge500";
export { ANVILBranding } from "./Layout/components/Footer/components/Branding/components/ANVILBranding/anvilBranding";
export { LabelIconMenuItem } from "./Layout/components/Header/components/Content/components/Navigation/components/NavigationMenuItems/components/LabelIconMenuItem/labelIconMenuItem";
8 changes: 8 additions & 0 deletions next/hooks/useFeatureFlag/common/entities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export enum FEATURES {
HEADER = "header",
}

export enum FLAG {
FALSE = "false",
TRUE = "true",
}
37 changes: 37 additions & 0 deletions next/hooks/useFeatureFlag/common/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { FEATURES } from "./entities";

const setOfFeatureFlags = new Set(Object.values(FEATURES) as string[]);

/**
* Set feature flags from URL.
*/
export function setFeatureFlags(): void {
if (typeof window === "undefined") return;
// Grab the search params from the URL.
const params = new URLSearchParams(window.location.search);
for (const [key, value] of params) {
if (setOfFeatureFlags.has(key)) {
setLocalStorage(key, value);
}
}
}

/**
* Return the value for the specified key.
* @param key - Key.
* @returns value.
*/
export function getLocalStorage(key: string): string | null {
if (typeof window === "undefined") return null;
return window?.localStorage?.getItem(key) ?? null;
}

/**
* Set the value for the specified key.
* @param key - Key.
* @param value - Value.
*/
export function setLocalStorage(key: string, value: string): void {
if (typeof window === "undefined") return;
window?.localStorage?.setItem(key, value);
}
21 changes: 21 additions & 0 deletions next/hooks/useFeatureFlag/useFeatureFlag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useEffect, useState } from "react";
import { FEATURES, FLAG } from "./common/entities";
import { getLocalStorage } from "./common/utils";

/**
* Determine if feature is available to user.
* @param featureFlag - Name of feature.
* @returns True if feature is available to user.
*/
export function useFeatureFlag(featureFlag: FEATURES): boolean {
/* Flag indicating if feature is available to user. */
const [isEnabled, setIsEnabled] = useState<boolean>(false);

/* Update state of enabled flag and redirect user if feature is not available to them. */
useEffect(() => {
const enabled = getLocalStorage(featureFlag) === FLAG.TRUE;
setIsEnabled(enabled);
}, [featureFlag]);

return isEnabled;
}
Loading

0 comments on commit 6b65163

Please sign in to comment.