UNCLASSIFIED

Commit 030cc96c authored by Ben Wynn's avatar Ben Wynn
Browse files

Merge branch 'develop' into 'staging'

content update and Nav work, SEO work, titles and descriptions

See merge request !13
parents 81e0c1e9 1864e436
Pipeline #205208 passed with stages
in 6 minutes and 22 seconds
...@@ -65,13 +65,15 @@ const mdPagesFromTemplate = async ( ...@@ -65,13 +65,15 @@ const mdPagesFromTemplate = async (
return; return;
} }
result.data.allMarkdownRemark.edges.forEach(({ node }) => { result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({ if (node.frontmatter.slug) {
path: node.frontmatter.slug, createPage({
component: pageTemplate, path: node.frontmatter.slug,
context: { component: pageTemplate,
// additional data can be passed via context context: {
slug: node.frontmatter.slug, // additional data can be passed via context
}, slug: node.frontmatter.slug,
}); },
});
}
}); });
}; };
...@@ -14,7 +14,7 @@ import theme from '../../styles/theme'; ...@@ -14,7 +14,7 @@ import theme from '../../styles/theme';
* color based on fixed state and page type. * color based on fixed state and page type.
*/ */
const StyledHeader = styled(GHeader)` const StyledHeader = styled(GHeader)`
z-index: 10; z-index: 25;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
...@@ -39,7 +39,7 @@ const Header = ({ transparent }) => { ...@@ -39,7 +39,7 @@ const Header = ({ transparent }) => {
<div ref={holderRef} style={{ holderStyles }}> <div ref={holderRef} style={{ holderStyles }}>
<div <div
ref={wrapperRef} ref={wrapperRef}
style={isFixed ? { ...wrapperStyles, ...{ zIndex: 10 } } : {}} style={isFixed ? { ...wrapperStyles, ...{ zIndex: 25 } } : {}}
> >
<StyledHeader <StyledHeader
sticky={isFixed} sticky={isFixed}
......
import React, { useState, useContext } from 'react'; import React, { useState, useContext } from 'react';
import { import { Box, Button, Text, Keyboard, Layer, ResponsiveContext } from 'grommet';
Box, import { Menu, FormUp, FormDown } from 'grommet-icons';
Button,
Keyboard,
Layer,
ThemeContext,
ResponsiveContext,
} from 'grommet';
import { Menu } from 'grommet-icons';
import { Link } from '../core'; import { Link } from '../core';
import { MegaMenu, MegaMobileMenu } from '../mega-menu'; import { MegaMenu, MegaMobileMenu } from '../mega-menu';
...@@ -29,15 +22,21 @@ const Nav = ({ sticky }) => { ...@@ -29,15 +22,21 @@ const Nav = ({ sticky }) => {
<Box <Box
as="nav" as="nav"
justify="center" justify="center"
gap="medium" align={sticky ? 'center' : 'end'}
gap="small"
direction={sticky ? 'row' : 'column'} direction={sticky ? 'row' : 'column'}
> >
<Box direction="row" justify="end" gap="large"> <Box
direction="row"
justify="end"
gap="large"
margin={{ right: sticky ? 'medium' : '0' }}
>
<Box justify="center"> <Box justify="center">
<Link <Link
to="/about-us" to="/about-us"
size="xsmall" size="xsmall"
color="white" color={sticky ? 'light-1' : 'white'}
style={{ textTransform: 'uppercase' }} style={{ textTransform: 'uppercase' }}
> >
About Us About Us
...@@ -47,27 +46,60 @@ const Nav = ({ sticky }) => { ...@@ -47,27 +46,60 @@ const Nav = ({ sticky }) => {
<Link <Link
to="/other-programs" to="/other-programs"
size="xsmall" size="xsmall"
color="white" color={sticky ? 'light-1' : 'white'}
style={{ textTransform: 'uppercase' }} style={{ textTransform: 'uppercase' }}
> >
Our Other Programs Our Other Programs
</Link> </Link>
</Box> </Box>
</Box> </Box>
<Box direction="row" justify="end" gap="large"> {sticky && (
<Box
height="1em"
width="2px"
background="light-1"
style={{ opacity: '0.4' }}
/>
)}
<Box
direction="row"
justify="end"
align="center"
gap={sticky ? 'small' : 'small'}
>
<Box justify="center"> <Box justify="center">
<ThemeContext.Extend value={{}}> <Box background={menuOpen ? 'white' : 'none'}>
<Button <Link
onClick={handleToggleMenu} onClick={handleToggleMenu}
secondary
color={menuOpen ? 'black' : 'white'} color={menuOpen ? 'black' : 'white'}
style={{ textTransform: 'uppercase' }} style={{ textTransform: 'uppercase' }}
size="small" >
label="Available Services" <Box
/> direction="row"
</ThemeContext.Extend> align="center"
pad={{ vertical: 'xsmall', horizontal: 'medium' }}
gap="small"
>
<Text weight="bold" size="small">
Available Services
</Text>
{menuOpen ? (
<FormUp color="accent-1" />
) : (
<FormDown color="accent-1" />
)}
</Box>
</Link>
</Box>
</Box> </Box>
<Box justify="center"> <Box
height="1em"
width="2px"
background="light-1"
style={{ opacity: '0.4' }}
/>
<Box justify="center" margin={{ left: 'medium' }}>
<Link <Link
to="/solutions" to="/solutions"
size="small" size="small"
......
/**
* SEO component that queries for data with
* Gatsby's useStaticQuery React hook
*
* See: https://www.gatsbyjs.com/docs/use-static-query/
*/
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
...@@ -41,9 +34,14 @@ function SEO({ description, lang, meta, title, image }) { ...@@ -41,9 +34,14 @@ function SEO({ description, lang, meta, title, image }) {
name: `description`, name: `description`,
content: metaDescription, content: metaDescription,
}, },
/**
* Home page does not send title, so uses default title. Any other page sends a
* title prop which is mixed with titleTemplate for the browser using the tittle Template
* prop above. But the same thing here is needed for the share title.
*/
{ {
property: `og:title`, property: `og:title`,
content: title, content: title ? `${title} - ${defaultTitle}` : defaultTitle,
}, },
{ {
property: `og:description`, property: `og:description`,
...@@ -63,7 +61,7 @@ function SEO({ description, lang, meta, title, image }) { ...@@ -63,7 +61,7 @@ function SEO({ description, lang, meta, title, image }) {
}, },
{ {
name: `twitter:title`, name: `twitter:title`,
content: title, content: title ? `${title} - ${defaultTitle}` : defaultTitle,
}, },
{ {
name: `twitter:description`, name: `twitter:description`,
......
import React from 'react';
import { Box, Text, ThemeContext } from 'grommet';
import { FormNext } from 'grommet-icons';
import Link from './Link';
const korolevFont = 'korolev, Helvetica Neue, Helvetica, Arial, sans-serif';
const themeExtend = {
text: {
font: {
family: korolevFont,
},
extend: () => ({ textTransform: 'uppercase', letterSpacing: '0.05em' }),
},
anchor: {
fontFamily: korolevFont,
},
};
const CtaLink = ({ children, ...rest }) => (
<ThemeContext.Extend value={themeExtend}>
<Box direction="row" justify="start" align="center">
<Link {...rest} color="black">
<Box direction="row" justify="start" align="center">
<Text size="small" weight="bold">
{children}
</Text>{' '}
<FormNext color="accent-1" />
</Box>
</Link>
</Box>
</ThemeContext.Extend>
);
export default CtaLink;
export { default as Link } from './Link'; export { default as Link } from './Link';
export { default as CtaLink } from './CtaLink';
export { default as Markdown } from './Markdown'; export { default as Markdown } from './Markdown';
export { default as PrimaryButton } from './PrimaryButton'; export { default as PrimaryButton } from './PrimaryButton';
export { default as SecondaryButton } from './SecondaryButton'; export { default as SecondaryButton } from './SecondaryButton';
import React from 'react';
import { StyledIcon } from 'grommet-icons/StyledIcon';
export const DtTriad = (props) => (
<StyledIcon viewBox="0 0 24 24" a11yTitle="DtTriad" {...props}>
<path
fill="none"
stroke="#000"
strokeWidth={props.strokeWidth || '1'}
d="M12,9.2c-1.4,0-2.5-1.1-2.5-2.5s1.1-2.5,2.5-2.5s2.5,1.1,2.5,2.5S13.4,9.2,12,9.2z M22.8,17.1
c0-1.4-1.1-2.5-2.5-2.5c-1.4,0-2.5,1.1-2.5,2.5s1.1,2.5,2.5,2.5C21.7,19.6,22.8,18.5,22.8,17.1z M5.9,17.1c0-1.4-1.1-2.5-2.5-2.5
s-2.5,1.1-2.5,2.5s1.1,2.5,2.5,2.5S5.9,18.5,5.9,17.1z M10.4,8.7L5,15.3 M18.8,15.3l-5.3-6.6"
/>
</StyledIcon>
);
...@@ -6,3 +6,4 @@ export * from './DtComputeStore'; ...@@ -6,3 +6,4 @@ export * from './DtComputeStore';
export * from './DtDataAnalysis'; export * from './DtDataAnalysis';
export * from './DtSquare'; export * from './DtSquare';
export * from './DtHex'; export * from './DtHex';
export * from './DtTriad';
import React from 'react'; import React, { useContext } from 'react';
import { Box, Text, Heading } from 'grommet'; import { Box, Text, Heading, ResponsiveContext, Layer } from 'grommet';
import styled from 'styled-components'; import styled from 'styled-components';
import { import {
DtNetConn, DtNetConn,
...@@ -14,14 +14,14 @@ import { Link } from '../core'; ...@@ -14,14 +14,14 @@ import { Link } from '../core';
const StyledMenu = styled(Box)` const StyledMenu = styled(Box)`
position: absolute; position: absolute;
top: ${(props) => (props.sticky ? '60px' : '100px')}; top: ${(props) => (props.sticky ? '48px' : '93px')};
left: 20px; left: 20px;
right: 20px; right: 20px;
`; `;
const Divider = ({ ...props }) => ( const Divider = ({ ...props }) => (
<Box <Box
margin={{ vertical: 'medium' }} margin={{ top: 'medium', bottom: 'medium', right: 'large' }}
height="2px" height="2px"
background="light-1" background="light-1"
{...props} {...props}
...@@ -36,102 +36,122 @@ const GroupHeader = ({ label, icon, overview }) => ( ...@@ -36,102 +36,122 @@ const GroupHeader = ({ label, icon, overview }) => (
margin={{ vertical: 'small' }} margin={{ vertical: 'small' }}
> >
{icon} {icon}
<Heading level={6} margin="none"> <Box direction="row" align="end" gap="small">
{label} <Heading level={6} margin="none">
</Heading> {label}
{overview && ( </Heading>
<Link to={overview} size="xsmall"> {overview && (
Overview <Link to={overview} size="xsmall">
</Link> Overview
)} </Link>
)}
</Box>
</Box> </Box>
); );
const MegaMenu = ({ sticky }) => ( const containerPad = {
<StyledMenu sticky={sticky}> xlarge: 'large',
<Box large: 'medium',
pad="large" medium: 'medium',
background="white" };
elevation="small"
style={{ zIndex: 20 }}
>
<Heading level={2} margin="none">
Available Services
</Heading>
<Text>
The following services are available to your organization through C3I&N
</Text>
<Box direction="row" gap="medium">
<Box border={{ side: 'right' }} basis="1/2">
<GroupHeader
label="Networking & Connectivity"
icon={<DtNetConn />}
overview="/networking-connectivity"
/>
<Box direction="row"> const MegaMenu = ({ sticky }) => {
<Box basis="1/2"> const size = useContext(ResponsiveContext);
<MenuGroup const isVert = size === 'medium';
title="Global Connectivity / WAN"
category="Global Connectivity / WAN" return (
/> <StyledMenu sticky={sticky}>
<MenuGroup <Layer />
title="Local Connectivity / BAN" <Box
category="Local Connectivity / BAN" pad={containerPad[size]}
/> background="white"
</Box> style={{ maxHeight: 'calc(100vh - 120px)' }}
<Box basis="1/2"> >
<MenuGroup title="Cloud Access" category="Cloud Access" /> <Heading level={2} margin="none">
<MenuGroup Available Services
title="Reference Architectures" </Heading>
category="Reference Architectures" <Text color="dark-1" size="small">
/> The following services are available to your organization through
<MenuGroup C3I&N
title="Virtual Private Connections" </Text>
category="Virtual Private Connections" <Box
/> direction={isVert ? 'column' : 'row'}
</Box> gap={isVert ? 'small' : 'large'}
</Box> pad={{ vertical: 'medium' }}
</Box> style={{ overflowY: 'auto' }}
<Box direction="row" basis="1/2"> >
<Box> <Box {...{ border: !isVert && { side: 'right' } }} basis="45%">
<Box> <GroupHeader
<GroupHeader label="Networking & Connectivity"
label="Compute & Store" icon={<DtNetConn />}
icon={<DtComputeStore />} overview="/networking-connectivity"
overview="/hosting-infrastructure" />
/>
<MenuGroup category="Compute & Store" /> <Box direction="row" flex={{ shrink: 0 }}>
</Box> <Box basis="1/2">
<Divider /> <MenuGroup
<Box> title="Global Connectivity / WAN"
<GroupHeader category="Global Connectivity / WAN"
label="Software Development & DevSecOps" />
icon={<DtDevSecOps />} <MenuGroup
/> title="Local Connectivity / BAN"
<MenuGroup category="Software Development & DevSecOps" /> category="Local Connectivity / BAN"
/>
</Box>
<Box basis="1/2">
<MenuGroup title="Cloud Access" category="Cloud Access" />
<MenuGroup
title="Reference Architectures"
category="Reference Architectures"
/>
<MenuGroup
title="Virtual Private Connections"
category="Virtual Private Connections"
/>
</Box>
</Box> </Box>
</Box> </Box>
<Box> {isVert && <Divider flex={{ grow: 0 }} />}
<Box> <Box direction="row" basis="55%" gap="large">
<GroupHeader label="Digital Engineering" icon={<DtDigiEng />} /> <Box basis="1/2">
<MenuGroup category="Digital Engineering" /> <Box>
</Box> <GroupHeader
<Divider /> label="Compute & Store"
<Box> icon={<DtComputeStore />}
<GroupHeader label="Communications" icon={<DtComms />} /> overview="/hosting-infrastructure"
<MenuGroup category="Communications" /> />
<MenuGroup category="Compute & Store" />
</Box>
<Divider />
<Box>
<GroupHeader
label="Software Development & DevSecOps"
icon={<DtDevSecOps />}
/>
<MenuGroup category="Software Development & DevSecOps" />
</Box>
</Box> </Box>
<Divider /> <Box basis="1/2">
<Box> <Box flex={{ shrink: 0 }}>
<GroupHeader label="Data Analysis" icon={<DtDataAnalysis />} /> <GroupHeader label="Digital Engineering" icon={<DtDigiEng />} />
<MenuGroup category="Data Analysis" /> <MenuGroup category="Digital Engineering" />
</Box>
<Divider />
<Box flex={{ shrink: 0 }}>
<GroupHeader label="Communications" icon={<DtComms />} />
<MenuGroup category="Communications" />
</Box>
<Divider />
<Box flex={{ shrink: 0 }}>
<GroupHeader label="Data Analysis" icon={<DtDataAnalysis />} />
<MenuGroup category="Data Analysis" />
</Box>
</Box> </Box>
</Box> </Box>
</Box> </Box>
</Box> </Box>
</Box> </StyledMenu>
</StyledMenu> );
); };
export default MegaMenu; export default MegaMenu;
...@@ -42,6 +42,7 @@ const MenuGroup = ({ category, title }) => { ...@@ -42,6 +42,7 @@ const MenuGroup = ({ category, title }) => {
key={item.id} key={item.id}
gap="small" gap="small"
pad={{ horizontal: 'large' }} pad={{ horizontal: 'large' }}
flex={{ shrink: 0 }}
> >
<Link to={item.frontmatter.slug} size="small"> <Link to={item.frontmatter.slug} size="small">
{item.frontmatter.title} {item.frontmatter.title}
......
import React, { useState } from 'react'; import React, { useState, useContext } from 'react';
import { Accordion, AccordionPanel, Box, Text } from 'grommet'; import {
Accordion,
AccordionPanel,
Box,
Text,
ResponsiveContext,
} from 'grommet';
import { FormUp, FormDown } from 'grommet-icons'; import { FormUp, FormDown } from 'grommet-icons';
import Reference from '../../icons/Reference'; import Reference from '../../icons/Reference';
import { MenuGroup } from '../../mega-menu'; import { MenuGroup } from '../../mega-menu';
const OfferHeader = ({ title, icon, description, active }) => ( const OfferHeader = ({ title, icon, description, active, isMobile }) => (
<Box <Box
direction="row" direction="row"
gap="medium" gap="medium"
pad="medium" pad={isMobile ? 'large' : 'medium'}
background="#eee" background="#eee"
round="small" round="small"
fill fill
...@@ -16,7 +22,7 @@ const OfferHeader = ({ title, icon, description, active }) => ( ...@@ -16,7 +22,7 @@ const OfferHeader = ({ title, icon, description, active }) => (
justify="between" justify="between"
> >
<Box direction="row" gap="medium"> <Box direction="row" gap="medium">
{icon} {!isMobile && <Box>{icon}</Box>}
<Box> <Box>
<Text>{title}</Text> <Text>{title}</Text>
{description && <Text size="small">{description}</Text>} {description && <Text size="small">{description}</Text>}
...@@ -27,17 +33,29 @@ const OfferHeader = ({ title, icon, description, active }) => ( ...@@ -27,17 +33,29 @@ const OfferHeader = ({ title, icon, description, active }) => (
</Box> </Box>
); );
const widths = {
xsmall: '100%',
small: '100%',
medium: '100%',
large: 'large',
xlarge: 'large',
};
const OfferAcc = () => { const OfferAcc = () => {
const [activeList, setActiveList] = useState([]); const [activeList, setActiveList] = useState([]);
const size = useContext(ResponsiveContext);
const isMobile = ['xsmall', 'small'].includes(size);
const handleChange = (list) => { const handleChange = (list) => {
setActiveList(list); setActiveList(list);
}; };
return ( return (
<Box width="large" pad={{ vertical: 'large' }}> <Box width={widths[size]} pad={{ vertical: 'large' }}>
<Accordion <Accordion
alignSelf="stretch" alignSelf="stretch"
gap="small" gap={isMobile ? 'large' : 'small'}
onActive={handleChange} onActive={handleChange}
a11yTitle="Solutions List" a11yTitle="Solutions List"
> >
...@@ -47,11 +65,12 @@ const OfferAcc = () => { ...@@ -47,11 +65,12 @@ const OfferAcc = () => {
title="Networking & Connectivity" title="Networking & Connectivity"
icon={<Reference name="Networking & Connectivity" />} icon={<Reference name="Networking & Connectivity" />}
active={activeList.includes(0)} active={activeList.includes(0)}
isMobile={isMobile}
/> />
} }
> >
<Box <Box
direction="row" direction={isMobile ? 'column' : 'row'}
pad={{ horizontal: 'large', vertical: 'medium' }} pad={{ horizontal: 'large', vertical: 'medium' }}
gap="large" gap="large"
> >
...@@ -84,6 +103,7 @@ const OfferAcc = () => { ...@@ -84,6 +103,7 @@ const OfferAcc = () => {
title="Compute & Store" title="Compute & Store"
icon={<Reference name="Compute & Store" />} icon={<Reference name="Compute & Store" />}
active={activeList.includes(1)} active={activeList.includes(1)}
isMobile={isMobile}
/> />
} }
> >
...@@ -103,6 +123,7 @@ const OfferAcc = () => { ...@@ -103,6 +123,7 @@ const OfferAcc = () => {
title="Software Development & DevSecOps" title="Software Development & DevSecOps"
icon={<Reference name="Software Development & DevSecOps" />} icon={<Reference name="Software Development & DevSecOps" />}
active={activeList.includes(2)} active={activeList.includes(2)}
isMobile={isMobile}
/> />
} }
> >
...@@ -122,6 +143,7 @@ const OfferAcc = () => { ...@@ -122,6 +143,7 @@ const OfferAcc = () => {
title="Digital Engineering" title="Digital Engineering"
icon={<Reference name="Digital Engineering" />} icon={<Reference name="Digital Engineering" />}
active={activeList.includes(3)} active={activeList.includes(3)}
isMobile={isMobile}
/> />
} }
> >
...@@ -141,6 +163,7 @@ const OfferAcc = () => { ...@@ -141,6 +163,7 @@ const OfferAcc = () => {
title="Communications" title="Communications"
icon={<Reference name="Communications" />} icon={<Reference name="Communications" />}
active={activeList.includes(4)} active={activeList.includes(4)}
isMobile={isMobile}
/> />
} }
> >
...@@ -160,6 +183,7 @@ const OfferAcc = () => { ...@@ -160,6 +183,7 @@ const OfferAcc = () => {
title="Data Analysis" title="Data Analysis"
icon={<Reference name="Data Analysis" />} icon={<Reference name="Data Analysis" />}
active={activeList.includes(5)} active={activeList.includes(5)}
isMobile={isMobile}
/> />
} }
> >
......
import React from 'react'; import React, { useContext } from 'react';
import { useStaticQuery, graphql } from 'gatsby'; import { useStaticQuery, graphql } from 'gatsby';
import { Box, Text, Heading, Paragraph } from 'grommet'; import { Box, Text, Heading, Paragraph, ResponsiveContext } from 'grommet';
import { DtNetConn } from '../../icons'; import { DtTriad } from '../../icons';
import Reference from '../../icons/Reference'; import Reference from '../../icons/Reference';
import { Link, PrimaryButton } from '../../core'; import { CtaLink, PrimaryButton } from '../../core';
const SolutionGroup = ({ node, basis, isMobile }) => (
<Box gap="medium" pad="medium" basis={isMobile ? 'auto' : '1/2'}>
<Box basis={isMobile ? 'auto' : '4em'} flex={{ shrink: 0 }}>
<Heading level={4} margin="0">
{node.frontmatter.useCase}
</Heading>
</Box>
<Box gap="medium" pad={{ vertical: 'medium' }} fill>
{node.frontmatter.categories.map((item) => (
<Box direction="row" gap="medium" key={item}>
<Reference name={item} size="20px" />
<Text size="small" color="dark-1">
{item}
</Text>
</Box>
))}
</Box>
<CtaLink to={node.frontmatter.slug}>Learn More</CtaLink>
</Box>
);
/** /**
* 2 column responsive grid block * 2 column responsive grid block
...@@ -31,14 +54,21 @@ const Solutions = () => { ...@@ -31,14 +54,21 @@ const Solutions = () => {
} }
`); `);
const size = useContext(ResponsiveContext);
const isMobile = ['xsmall', 'small'].includes(size);
// Use the first 2 items from the solutions list // Use the first 2 items from the solutions list
const s1 = allMarkdownRemark.edges[0].node; const s1 = allMarkdownRemark.edges[0].node;
const s2 = allMarkdownRemark.edges[1].node; const s2 = allMarkdownRemark.edges[1].node;
return ( return (
<Box align="center" pad={{ vertical: 'large' }}> <Box
align="center"
pad={{ vertical: 'large' }}
margin={{ top: isMobile ? '100px' : '0' }}
>
<Box align="center" style={{ position: 'relative' }}> <Box align="center" style={{ position: 'relative' }}>
<Box style={{ zIndex: 2 }}> <Box style={{ zIndex: 2 }} align="center">
<Heading <Heading
level={1} level={1}
as="h2" as="h2"
...@@ -52,41 +82,26 @@ const Solutions = () => { ...@@ -52,41 +82,26 @@ const Solutions = () => {
</Paragraph> </Paragraph>
</Box> </Box>
<DtNetConn <DtTriad
size="300" size="400"
color="#F5F5F5" color="#F5F5F5"
style={{ position: 'absolute', top: '0', zIndex: 0 }} strokeWidth="1.5"
style={{
position: 'absolute',
top: '50%',
transform: 'translateY(-50%)',
zIndex: 0,
}}
/> />
</Box> </Box>
<Box direction="row" width="large" gap="large" style={{ zIndex: 2 }}> <Box
<Box gap="medium" basis="1/2"> direction={isMobile ? 'column' : 'row'}
<Text weight="bold" as="p"> width={isMobile ? 'medium' : 'large'}
{s1.frontmatter.useCase} gap="large"
</Text> style={{ zIndex: 2 }}
{s1.frontmatter.categories.map((item) => ( >
<Box direction="row" gap="medium" key={item}> <SolutionGroup node={s1} isMobile={isMobile} />
<Reference name={item} size="20px" /> <SolutionGroup node={s2} isMobile={isMobile} />
<Text size="small" color="dark-1">
{item}
</Text>
</Box>
))}
<Link to={s1.frontmatter.slug}>Learn More</Link>
</Box>
<Box gap="medium" basis="1/2">
<Text weight="bold" as="p">
{s2.frontmatter.useCase}
</Text>
{s2.frontmatter.categories.map((item) => (
<Box direction="row" gap="medium" key={item}>
<Reference name={item} size="20px" />
<Text size="small" color="dark-1">
{item}
</Text>
</Box>
))}
<Link to={s2.frontmatter.slug}>Learn More</Link>
</Box>
</Box> </Box>
<Box width="300px" margin="large"> <Box width="300px" margin="large">
<PrimaryButton label="SEE MORE SOLUTIONS" /> <PrimaryButton label="SEE MORE SOLUTIONS" />
......
...@@ -4,7 +4,7 @@ import { Box, Heading, Paragraph, ResponsiveContext } from 'grommet'; ...@@ -4,7 +4,7 @@ import { Box, Heading, Paragraph, ResponsiveContext } from 'grommet';
import { useStaticQuery, graphql } from 'gatsby'; import { useStaticQuery, graphql } from 'gatsby';
import { DtSquare } from '../../icons'; import { DtSquare } from '../../icons';
import { Container, Column } from '../../layout'; import { Container, Column } from '../../layout';
import { Link } from '../../core'; import { CtaLink } from '../../core';
import Classification from '../../Classification'; import Classification from '../../Classification';
const listQuery = graphql` const listQuery = graphql`
...@@ -37,7 +37,7 @@ const ServiceItem = ({ node, pad }) => ( ...@@ -37,7 +37,7 @@ const ServiceItem = ({ node, pad }) => (
<Paragraph fill>{node.frontmatter.excerpt || node.excerpt}</Paragraph> <Paragraph fill>{node.frontmatter.excerpt || node.excerpt}</Paragraph>
</Box> </Box>
<Link to={node.frontmatter.slug}>Learn More ></Link> <CtaLink to={node.frontmatter.slug}>Learn More</CtaLink>
</Box> </Box>
); );
...@@ -45,8 +45,8 @@ const rowPad = { ...@@ -45,8 +45,8 @@ const rowPad = {
xsmall: '0', xsmall: '0',
small: '0', small: '0',
medium: 'medium', medium: 'medium',
large: 'large', large: 'medium',
xlarge: 'large', xlarge: 'medium',
}; };
const ServiceList = ({ categories }) => { const ServiceList = ({ categories }) => {
...@@ -63,7 +63,7 @@ const ServiceList = ({ categories }) => { ...@@ -63,7 +63,7 @@ const ServiceList = ({ categories }) => {
const isMobile = ['xsmall', 'small'].includes(size); const isMobile = ['xsmall', 'small'].includes(size);
return ( return (
<Box pad={{ vertical: 'large' }} background="white"> <Box pad={{ vertical: 'large' }} background="white" style={{ zIndex: 5 }}>
{catGroup.map((group, i) => ( {catGroup.map((group, i) => (
<Box key={categories[i]} gap="small"> <Box key={categories[i]} gap="small">
{categories.length > 1 && ( {categories.length > 1 && (
...@@ -94,7 +94,7 @@ const ServiceList = ({ categories }) => { ...@@ -94,7 +94,7 @@ const ServiceList = ({ categories }) => {
gap="large" gap="large"
key={item1.id} key={item1.id}
> >
{item1 && <ServiceItem node={item1} />} {item1 && <ServiceItem node={item1} pad={rowPad[size]} />}
{item2 && <ServiceItem node={item2} pad={rowPad[size]} />} {item2 && <ServiceItem node={item2} pad={rowPad[size]} />}
</Box> </Box>
); );
......
...@@ -2,7 +2,7 @@ import React from 'react'; ...@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Box, Heading, Paragraph, Text } from 'grommet'; import { Box, Heading, Paragraph, Text } from 'grommet';
import { useStaticQuery, graphql } from 'gatsby'; import { useStaticQuery, graphql } from 'gatsby';
import { Link } from '../../core'; import { CtaLink } from '../../core';
import Classification from '../../Classification'; import Classification from '../../Classification';
const listQuery = graphql` const listQuery = graphql`
...@@ -33,28 +33,32 @@ const ServiceItem = ({ node, pad }) => ( ...@@ -33,28 +33,32 @@ const ServiceItem = ({ node, pad }) => (
{node.frontmatter.title} {node.frontmatter.title}
</Heading> </Heading>
<Box direction="row" gap="medium" margin={{ bottom: 'medium' }}> <Box direction="row" gap="medium" margin={{ bottom: 'medium' }}>
{node.frontmatter.categories.map((item) => ( {node.frontmatter.categories &&
<Text key={item} color="dark-1" size="small"> node.frontmatter.categories.map((item) => (
{item} <Text key={item} color="dark-1" size="small">
</Text> {item}
))} </Text>
))}
</Box> </Box>
<Classification levels={node.frontmatter.levels} /> {node.frontmatter.levels && (
<Classification levels={node.frontmatter.levels} />
)}
{/* Undo this "flex" if we don't want learn more to line up */} {/* Undo this "flex" if we don't want learn more to line up */}
<Box flex="grow" pad={{ vertical: pad }}> <Box flex="grow" pad={{ vertical: pad }}>
<Paragraph fill>{node.frontmatter.excerpt || node.excerpt}</Paragraph> <Paragraph fill>{node.frontmatter.excerpt || node.excerpt}</Paragraph>
</Box> </Box>
{node.frontmatter.slug && (
<Link to={node.frontmatter.slug}>Learn More ></Link> <CtaLink to={node.frontmatter.slug}>Learn More</CtaLink>
)}
</Box> </Box>
); );
const SolutionList = ({ shoppable, nonShoppable }) => { const SolutionList = ({ list }) => {
const { const {
allMarkdownRemark: { nodes }, allMarkdownRemark: { nodes },
} = useStaticQuery(listQuery); } = useStaticQuery(listQuery);
const ordered = shoppable.reduce((acc, curr, i) => { const ordered = list.reduce((acc, curr, i) => {
const matchingNode = nodes.find((node) => { const matchingNode = nodes.find((node) => {
const matchTitle = node.frontmatter.shortTitle || node.frontmatter.title; const matchTitle = node.frontmatter.shortTitle || node.frontmatter.title;
return matchTitle === curr; return matchTitle === curr;
...@@ -75,21 +79,12 @@ const SolutionList = ({ shoppable, nonShoppable }) => { ...@@ -75,21 +79,12 @@ const SolutionList = ({ shoppable, nonShoppable }) => {
<ServiceItem node={node} key={node.id} /> <ServiceItem node={node} key={node.id} />
) )
)} )}
{nonShoppable &&
nonShoppable.map((node) => (
<Box pad="medium" key={node}>
<Heading level={4} margin={{ vertical: 'xsmall' }}>
{node}
</Heading>
</Box>
))}
</Box> </Box>
); );
}; };
SolutionList.propTypes = { SolutionList.propTypes = {
shoppable: PropTypes.array.isRequired, list: PropTypes.array.isRequired,
nonShoppable: PropTypes.array,
}; };
export default SolutionList; export default SolutionList;
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
slug: '/services/af7' slug: '/services/af7'
title: 'Air Force Special Enclave Video Enterprise Network (AF7)' title: 'Air Force Special Enclave Video Enterprise Network (AF7)'
shortTitle: 'AF7' shortTitle: 'AF7'
categories: categories:
- Communications - Communications
levels: levels:
- S-SAR - S-SAR
......
...@@ -2,11 +2,16 @@ ...@@ -2,11 +2,16 @@
slug: '/services/afsen-coin' slug: '/services/afsen-coin'
title: 'AFSEN COIN' title: 'AFSEN COIN'
shortTitle: 'COIN' shortTitle: 'COIN'
categories: categories:
- Networking & Connectivity - Networking & Connectivity
- Global Connectivity / WAN - Global Connectivity / WAN
levels:
- S-SAR
- S-SCI
- TS-SAR
- TS-SCI
excerpt: 'AFSEN-COIN is designed to provide a standardized means of information transportation to improve service and connectivity between locations.' excerpt: 'AFSEN-COIN is designed to provide a standardized means of information transportation to improve service and connectivity between locations.'
updated: March 23, 2021 at 2:54:52 PM EDT updated: March 26
--- ---
AFSEN-COIN is a Virtual Private Network (VPN) service provided through the Defense Information Systems Agency (DISA) Global Information Grid (GIG). AFSEN-COIN provides the transport pipe for Secret//Special Access Required (SAR) up to Top Secret Sensitive Compartmented Information (SCI)//SAR traffic that is National Security Agency (NSA) Type-1 encrypted using DISA’s Layer 3-VPN service for long-haul transport. AFSEN-COIN provides customers with dedicated transport/bandwidth for Special Access Program (SAP) missions without having to compete with existing NIPRNet bandwidth. Private Network (VPN) service provided through the Defense Information Systems Agency (DISA) Global Information Grid (GIG). AFSEN-COIN provides the transport pipe for Secret//Special Access Required (SAR) up to Top Secret Sensitive Compartmented Information (SCI)//SAR traffic that is National Security Agency (NSA) Type-1 encrypted using DISA’s Layer 3-VPN service for long-haul transport. AFSEN-COIN provides customers with dedicated transport/bandwidth for Special Access Program (SAP) missions without having to compete with existing NIPRNet bandwidth. AFSEN-COIN is a Virtual Private Network (VPN) service provided through the Defense Information Systems Agency (DISA) Global Information Grid (GIG). AFSEN-COIN provides the transport pipe for Secret//Special Access Required (SAR) up to Top Secret Sensitive Compartmented Information (SCI)//SAR traffic that is National Security Agency (NSA) Type-1 encrypted using DISA’s Layer 3-VPN service for long-haul transport. AFSEN-COIN provides customers with dedicated transport/bandwidth for Special Access Program (SAP) missions without having to compete with existing NIPRNet bandwidth. Private Network (VPN) service provided through the Defense Information Systems Agency (DISA) Global Information Grid (GIG). AFSEN-COIN provides the transport pipe for Secret//Special Access Required (SAR) up to Top Secret Sensitive Compartmented Information (SCI)//SAR traffic that is National Security Agency (NSA) Type-1 encrypted using DISA’s Layer 3-VPN service for long-haul transport. AFSEN-COIN provides customers with dedicated transport/bandwidth for Special Access Program (SAP) missions without having to compete with existing NIPRNet bandwidth.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
slug: '/services/base-it-infrastructure' slug: '/services/base-it-infrastructure'
title: 'Base IT Infrastructure' title: 'Base IT Infrastructure'
shortTitle: 'BITI' shortTitle: 'BITI'
categories: categories:
- Networking & Connectivity - Networking & Connectivity
- Local Connectivity / BAN - Local Connectivity / BAN
- Global Connectivity / WAN - Global Connectivity / WAN
...@@ -10,20 +10,20 @@ levels: ...@@ -10,20 +10,20 @@ levels:
- U - U
- S - S
excerpt: 'Base IT Infrastructure services are centrally managed to provide both wired and wireless WAN and BAN capabilities.' excerpt: 'Base IT Infrastructure services are centrally managed to provide both wired and wireless WAN and BAN capabilities.'
updated: March 23, 2021 at 2:54:52 PM EDT updated: March 26
--- ---
**Wired** **Wired**
- All switches, critical and non-critical, to be replaced with improved technology. - All switches, critical and non-critical, to be replaced with improved technology.
- Software Defined Networking (SDN) capable - Software Defined Networking (SDN) capable
- Enhanced network security (802.1x, 2FA) - Enhanced network security (802.1x, 2FA)
**Wireless** **Wireless**
- Replacement/addition of facility wireless and flight-line wireless. - Replacement/addition of facility wireless and flight-line wireless.
- Wi-Fi 6 capable - Wi-Fi 6 capable
- Citizens Broadband Radio Service (CBRS) capable (flight-line only) - Citizens Broadband Radio Service (CBRS) capable (flight-line only)
- Private/Public/5G LTE delivery (flight-line only) - Private/Public/5G LTE delivery (flight-line only)
**Centralized Management** **Centralized Management**
- Deploy centralized management system for management of wireless, wired and deployment of security policies. - Deploy centralized management system for management of wireless, wired and deployment of security policies.
......
...@@ -3,8 +3,15 @@ slug: '/services/cloud-gateway' ...@@ -3,8 +3,15 @@ slug: '/services/cloud-gateway'
title: 'Cloud Gateway' title: 'Cloud Gateway'
categories: categories:
- Network & Connectivity - Network & Connectivity
- Cloud Accesslevels - Cloud Access
levels:
- S
- S-SAR
- S-SCI
- TS
- TS-SAR
- TS-SCI
excerpt: 'Cloud Gateway provides access to approved SAP Clouds & Services, SAP Meet Me Point (MMPs), and COMSEC collocation by offering high speed Cloud access and leverages common transports. It is tailored towards DoD SAP and ICON Defense Industrial Based (DIB) participants' excerpt: 'Cloud Gateway provides access to approved SAP Clouds & Services, SAP Meet Me Point (MMPs), and COMSEC collocation by offering high speed Cloud access and leverages common transports. It is tailored towards DoD SAP and ICON Defense Industrial Based (DIB) participants'
updated: March 23, 2021 at 2:54:52 PM EDT updated: March 26
--- ---
...@@ -21,16 +21,16 @@ CORE is an Air Force Special Access Program (SAP) suite of services approved for ...@@ -21,16 +21,16 @@ CORE is an Air Force Special Access Program (SAP) suite of services approved for
- Consolidates disparate architectures - Consolidates disparate architectures
- Eliminates secure faxing and human courier time - Eliminates secure faxing and human courier time
- Webmail service - Webmail service
- Adapts based on user clearances - Adapts based on user clearances
- No limit on inbox size - No limit on inbox size
- Attach files - Attach files
- Cloud-based file transfer - Cloud-based file transfer
- Multi-level Compartmentalization - Multi-level Compartmentalization
- Adapts based on user clearances - Adapts based on user clearances
- 3rd Party Introduction - 3rd Party Introduction
- User SAP accesses pulled from JADE - User SAP accesses pulled from JADE
- Strips PII information for general users - Strips PII information for general users
### Requirements ### Requirements
All necessary forms are provided by the Rock Connections Team All necessary forms are provided by the Rock Connections Team
......
...@@ -6,7 +6,7 @@ categories: ...@@ -6,7 +6,7 @@ categories:
levels: levels:
- U - U
excerpt: 'An enterprise Big Data Analytics platform hosted on Cloud One that provides advanced data analytics and data management tools up to IL4.' excerpt: 'An enterprise Big Data Analytics platform hosted on Cloud One that provides advanced data analytics and data management tools up to IL4.'
updated: March 23, 2021 at 2:54:52 PM EDT updated: March 26
--- ---
D1scovery provides an operational environment for analytics-based solutions and gives users access to cutting-edge commercial business intelligence and advanced data analytics tools and environment on Microsoft’s Azure Government Cloud. D1scovery provides an operational environment for analytics-based solutions and gives users access to cutting-edge commercial business intelligence and advanced data analytics tools and environment on Microsoft’s Azure Government Cloud.
...@@ -15,6 +15,7 @@ D1scovery provides an operational environment for analytics-based solutions and ...@@ -15,6 +15,7 @@ D1scovery provides an operational environment for analytics-based solutions and
### Benefits & Features ### Benefits & Features
**Benefits** **Benefits**
- Reduce cost and time needed to field Data Analytics Solutions with Data Lab sandbox to test analyses and draft solutions. - Reduce cost and time needed to field Data Analytics Solutions with Data Lab sandbox to test analyses and draft solutions.
- Publish vetted analytic solutions that can be shared with any CAC user via URL - Publish vetted analytic solutions that can be shared with any CAC user via URL
- Access a metadata catalog and Data Specialists to explore over 50 data sources and existing solutions - Access a metadata catalog and Data Specialists to explore over 50 data sources and existing solutions
...@@ -23,6 +24,7 @@ D1scovery provides an operational environment for analytics-based solutions and ...@@ -23,6 +24,7 @@ D1scovery provides an operational environment for analytics-based solutions and
- Utilize a comprehensive knowledge portal and on-demand toolbox resources to reduce training and start-up time. - Utilize a comprehensive knowledge portal and on-demand toolbox resources to reduce training and start-up time.
**Available Features** **Available Features**
- Apache MiFI - Apache MiFI
- Apache Spark - Apache Spark
- Azure Data Factory - Azure Data Factory
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment