Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add catalog/explorer chooser to "consortia pages" header (#2862) #2875

Merged
merged 1 commit into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading