parent
467edd24e2
commit
c39536677b
@ -25,6 +25,7 @@
|
|||||||
"joyent-icons": "^4.0.0",
|
"joyent-icons": "^4.0.0",
|
||||||
"joyent-ui-toolkit": "^4.5.0",
|
"joyent-ui-toolkit": "^4.5.0",
|
||||||
"lodash.chunk": "^4.2.0",
|
"lodash.chunk": "^4.2.0",
|
||||||
|
"lodash.keys": "^4.2.0",
|
||||||
"outy": "^0.1.2",
|
"outy": "^0.1.2",
|
||||||
"param-case": "^2.1.1",
|
"param-case": "^2.1.1",
|
||||||
"pascal-case": "^2.0.1",
|
"pascal-case": "^2.0.1",
|
||||||
|
@ -91,6 +91,10 @@ export const Divider = emotion('div')`
|
|||||||
height: ${remcalc(36)};
|
height: ${remcalc(36)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const Space = emotion('div')`
|
||||||
|
width: ${remcalc(6)};
|
||||||
|
`;
|
||||||
|
|
||||||
export const Row = emotion('div')`
|
export const Row = emotion('div')`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -14,7 +14,8 @@ export {
|
|||||||
Icon as HeaderItemIcon,
|
Icon as HeaderItemIcon,
|
||||||
FlexibleSpace as HeaderFlexibleSpaceItem,
|
FlexibleSpace as HeaderFlexibleSpaceItem,
|
||||||
Divider as HeaderDividerItem,
|
Divider as HeaderDividerItem,
|
||||||
SubContent as HeaderItemSubContent
|
SubContent as HeaderItemSubContent,
|
||||||
|
Space as HeaderSpace
|
||||||
} from './header';
|
} from './header';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -44,39 +44,40 @@ const getDatacenters = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Datacenters = ({ regions = [] }) => (
|
const Datacenters = ({ expanded, regions = [] }) =>
|
||||||
<Overlay>
|
expanded ? (
|
||||||
{regions.map(({ name, slug, places }) => (
|
<Overlay>
|
||||||
<div key={slug}>
|
{regions.map(({ name, slug, places }) => (
|
||||||
<TitleContainer>
|
<div key={slug}>
|
||||||
<Grid>
|
<TitleContainer>
|
||||||
<Row>
|
<Grid>
|
||||||
<Col>
|
|
||||||
<DatacenterRegion>{name}</DatacenterRegion>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Grid>
|
|
||||||
</TitleContainer>
|
|
||||||
<Container>
|
|
||||||
<Grid>
|
|
||||||
<RegionContainer>
|
|
||||||
<Row>
|
<Row>
|
||||||
{places.map(({ name, slug, datacenters }) => (
|
<Col>
|
||||||
<Col key={slug} xs={12} md={6} lg={3}>
|
<DatacenterRegion>{name}</DatacenterRegion>
|
||||||
<DatacenterPlace>{name}</DatacenterPlace>
|
</Col>
|
||||||
{datacenters.map(({ name, slug }) => (
|
|
||||||
<Datacenter key={slug}>{name}</Datacenter>
|
|
||||||
))}
|
|
||||||
</Col>
|
|
||||||
))}
|
|
||||||
</Row>
|
</Row>
|
||||||
</RegionContainer>
|
</Grid>
|
||||||
</Grid>
|
</TitleContainer>
|
||||||
</Container>
|
<Container>
|
||||||
</div>
|
<Grid>
|
||||||
))}
|
<RegionContainer>
|
||||||
</Overlay>
|
<Row>
|
||||||
);
|
{places.map(({ name, slug, datacenters }) => (
|
||||||
|
<Col key={slug} xs={12} md={6} lg={3}>
|
||||||
|
<DatacenterPlace>{name}</DatacenterPlace>
|
||||||
|
{datacenters.map(({ name, slug }) => (
|
||||||
|
<Datacenter key={slug}>{name}</Datacenter>
|
||||||
|
))}
|
||||||
|
</Col>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
</RegionContainer>
|
||||||
|
</Grid>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</Overlay>
|
||||||
|
) : null;
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
graphql(getDatacenters, {
|
graphql(getDatacenters, {
|
||||||
|
@ -20,62 +20,69 @@ const Container = emotion('div')`
|
|||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const getHeader = gql`
|
const GetCategories = gql`
|
||||||
{
|
{
|
||||||
categories @client {
|
categories @client {
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
services @client {
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const GetProducts = gql`
|
||||||
|
{
|
||||||
|
products {
|
||||||
name
|
name
|
||||||
description
|
description
|
||||||
category
|
category
|
||||||
slug
|
url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Services = ({ categories = [] }) => (
|
const Services = ({ expanded = false, categories = [], products }) =>
|
||||||
<Overlay>
|
expanded ? (
|
||||||
<Container>
|
<Overlay>
|
||||||
<Grid>
|
<Container>
|
||||||
{chunk(categories, 4).map(chunk => (
|
<Grid>
|
||||||
<Row>
|
{chunk(
|
||||||
{chunk.map(({ name, services }) => (
|
categories.map(({ slug, ...category }) => ({
|
||||||
<Col xs={12} sm={6} md={4} lg={3}>
|
...category,
|
||||||
<ServiceCategory>{name}</ServiceCategory>
|
services: products.filter(({ category }) => category === slug),
|
||||||
{services.map(({ name, description }) => (
|
slug
|
||||||
<Service>
|
})),
|
||||||
<ServiceName>{name}</ServiceName>
|
4
|
||||||
<ServiceDescription>{description}</ServiceDescription>
|
).map(chunk => (
|
||||||
</Service>
|
<Row>
|
||||||
))}
|
{chunk.map(({ name, services }) => (
|
||||||
</Col>
|
<Col xs={12} sm={6} md={4} lg={3}>
|
||||||
))}
|
<ServiceCategory>{name}</ServiceCategory>
|
||||||
</Row>
|
{services.map(({ name, description }) => (
|
||||||
))}
|
<Service>
|
||||||
</Grid>
|
<ServiceName>{name}</ServiceName>
|
||||||
</Container>
|
<ServiceDescription>{description}</ServiceDescription>
|
||||||
</Overlay>
|
</Service>
|
||||||
);
|
))}
|
||||||
|
</Col>
|
||||||
|
))}
|
||||||
|
</Row>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</Container>
|
||||||
|
</Overlay>
|
||||||
|
) : null;
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
graphql(getHeader, {
|
graphql(GetCategories, {
|
||||||
props: ({ data }) => {
|
props: ({ data }) => {
|
||||||
const {
|
const { categories = [] } = data;
|
||||||
categories = [],
|
return { categories };
|
||||||
services = [],
|
}
|
||||||
loading = false,
|
}),
|
||||||
error = null
|
graphql(GetProducts, {
|
||||||
} = data;
|
props: ({ data }) => {
|
||||||
|
const { products = [] } = data;
|
||||||
const _categories = categories.map(({ slug, ...category }) => ({
|
return { products };
|
||||||
...category,
|
|
||||||
services: services.filter(({ category }) => category === slug),
|
|
||||||
slug
|
|
||||||
}));
|
|
||||||
|
|
||||||
return { categories: _categories, loading, error };
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)(Services);
|
)(Services);
|
||||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import { graphql, compose } from 'react-apollo';
|
import { graphql, compose } from 'react-apollo';
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import pascalCase from 'pascal-case';
|
import pascalCase from 'pascal-case';
|
||||||
|
import keys from 'lodash.keys';
|
||||||
|
|
||||||
import { DataCenterIcon, TritonIcon, ServicesIcon } from './components';
|
import { DataCenterIcon, TritonIcon, ServicesIcon } from './components';
|
||||||
import * as Overlays from './containers';
|
import * as Overlays from './containers';
|
||||||
@ -15,7 +16,8 @@ import {
|
|||||||
HeaderItemSubContent,
|
HeaderItemSubContent,
|
||||||
HeaderItemIcon,
|
HeaderItemIcon,
|
||||||
HeaderFlexibleSpaceItem,
|
HeaderFlexibleSpaceItem,
|
||||||
HeaderDividerItem
|
HeaderDividerItem,
|
||||||
|
HeaderSpace
|
||||||
} from './components';
|
} from './components';
|
||||||
|
|
||||||
const updateHeaderMutation = gql`
|
const updateHeaderMutation = gql`
|
||||||
@ -39,20 +41,6 @@ const getAccount = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Panel = ({ name = '', expanded = false, children, ...rest }) => {
|
|
||||||
if (!expanded) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const overlay = Overlays[pascalCase(name)];
|
|
||||||
|
|
||||||
if (!overlay) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return React.createElement(overlay, rest, children);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Navigation = ({ login, toggleSectionOpen, isOpen, activePanel }) => (
|
const Navigation = ({ login, toggleSectionOpen, isOpen, activePanel }) => (
|
||||||
<Header onOutsideClick={() => toggleSectionOpen()}>
|
<Header onOutsideClick={() => toggleSectionOpen()}>
|
||||||
<HeaderRow>
|
<HeaderRow>
|
||||||
@ -64,7 +52,7 @@ const Navigation = ({ login, toggleSectionOpen, isOpen, activePanel }) => (
|
|||||||
onClick={() => toggleSectionOpen('services')}
|
onClick={() => toggleSectionOpen('services')}
|
||||||
active={isOpen && activePanel === 'services'}
|
active={isOpen && activePanel === 'services'}
|
||||||
>
|
>
|
||||||
<HeaderItemContent>Services</HeaderItemContent>
|
<HeaderItemContent>Products & Services</HeaderItemContent>
|
||||||
<HeaderItemIcon>
|
<HeaderItemIcon>
|
||||||
<ServicesIcon light />
|
<ServicesIcon light />
|
||||||
</HeaderItemIcon>
|
</HeaderItemIcon>
|
||||||
@ -77,7 +65,9 @@ const Navigation = ({ login, toggleSectionOpen, isOpen, activePanel }) => (
|
|||||||
active={isOpen && activePanel === 'datacenter'}
|
active={isOpen && activePanel === 'datacenter'}
|
||||||
>
|
>
|
||||||
<HeaderItemContent>
|
<HeaderItemContent>
|
||||||
<HeaderItemSubContent>Data Center:</HeaderItemSubContent> us-east-1
|
<HeaderItemSubContent>Data Center:</HeaderItemSubContent>
|
||||||
|
<HeaderSpace />
|
||||||
|
<span>us-east-1</span>
|
||||||
</HeaderItemContent>
|
</HeaderItemContent>
|
||||||
<HeaderItemIcon>
|
<HeaderItemIcon>
|
||||||
<DataCenterIcon light />
|
<DataCenterIcon light />
|
||||||
@ -87,7 +77,9 @@ const Navigation = ({ login, toggleSectionOpen, isOpen, activePanel }) => (
|
|||||||
{login ? (
|
{login ? (
|
||||||
<HeaderItem>
|
<HeaderItem>
|
||||||
<HeaderItemContent>
|
<HeaderItemContent>
|
||||||
<HeaderItemSubContent>Account:</HeaderItemSubContent> {login}
|
<HeaderItemSubContent>Account:</HeaderItemSubContent>
|
||||||
|
<HeaderSpace />
|
||||||
|
{login}
|
||||||
</HeaderItemContent>
|
</HeaderItemContent>
|
||||||
<HeaderItemIcon>
|
<HeaderItemIcon>
|
||||||
<Avatar />
|
<Avatar />
|
||||||
@ -95,7 +87,11 @@ const Navigation = ({ login, toggleSectionOpen, isOpen, activePanel }) => (
|
|||||||
</HeaderItem>
|
</HeaderItem>
|
||||||
) : null}
|
) : null}
|
||||||
</HeaderRow>
|
</HeaderRow>
|
||||||
<Panel expanded={isOpen} name={activePanel} />
|
{keys(Overlays).map(panelName =>
|
||||||
|
React.createElement(Overlays[panelName], {
|
||||||
|
expanded: isOpen && panelName === pascalCase(activePanel)
|
||||||
|
})
|
||||||
|
)}
|
||||||
</Header>
|
</Header>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -117,92 +117,6 @@ export default {
|
|||||||
name: 'Help & Support',
|
name: 'Help & Support',
|
||||||
__typename: 'Category'
|
__typename: 'Category'
|
||||||
}
|
}
|
||||||
]),
|
|
||||||
services: dataSlugFromObjects([
|
|
||||||
{
|
|
||||||
name: 'VMs & Containers',
|
|
||||||
description: 'Run VMs and bare metal containers',
|
|
||||||
category: 'compute',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Converged Analytics',
|
|
||||||
description: 'Map reduce and ETL on your objects',
|
|
||||||
category: 'compute',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'VLANs',
|
|
||||||
description: 'Wire your appliction your way',
|
|
||||||
category: 'network',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Subnets',
|
|
||||||
description: 'A network for everything',
|
|
||||||
category: 'network',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Firewall Rules',
|
|
||||||
description: 'Control the bits coming and going',
|
|
||||||
category: 'network',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Service Status',
|
|
||||||
description: 'Write here about Service Status',
|
|
||||||
category: 'help-support',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Contact Support',
|
|
||||||
description: 'Chat to us via phone or email',
|
|
||||||
category: 'help-support',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Support Plans',
|
|
||||||
description: 'Write here about Support Plans',
|
|
||||||
category: 'help-support',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Getting Started',
|
|
||||||
description: 'Write here about Getting Started',
|
|
||||||
category: 'help-support',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Triton Object Storage',
|
|
||||||
description: 'Modern cloud object storage',
|
|
||||||
category: 'storage',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'S3 Compatibility Bridge',
|
|
||||||
description: 'Modern storage, legacy compatibility',
|
|
||||||
category: 'storage',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Triton Volumes',
|
|
||||||
description: 'Network filesystems for your apps',
|
|
||||||
category: 'storage',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Role Based Access Control',
|
|
||||||
description: 'Manage users within your account',
|
|
||||||
category: 'access',
|
|
||||||
__typename: 'Service'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Firewall Rules',
|
|
||||||
description: 'Inspect all the bytes',
|
|
||||||
category: 'access',
|
|
||||||
__typename: 'Service'
|
|
||||||
}
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user