Add icons to service list and tidy up

This commit is contained in:
JUDIT GRESKOVITS 2017-03-20 15:58:47 +00:00 committed by Judit Greskovits
parent 9a1a84510f
commit c06bbf4e31
11 changed files with 138 additions and 24 deletions

View File

@ -1,20 +1,33 @@
import React from 'react'; import React from 'react';
import { MetricGraph, MetricView } from '@ui/components/metric'; import {
import PropTypes from '@root/prop-types'; MetricGraph,
MetricView,
MiniMetricMeta,
MiniMetricTitle,
MiniMetricSubtitle
} from '@ui/components/metric';
const MetricItem = ({ const MetricItem = ({
uuid, uuid,
data data
}) => ( }) => (
<MetricView borderless mini> <MetricView borderless mini>
<MetricGraph data={data} /> <MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MetricGraph
data={data}
width={160}
height={72}
/>
</MetricView> </MetricView>
); );
MetricItem.propTypes = { MetricItem.propTypes = {
uuid: React.PropTypes.string, uuid: React.PropTypes.string,
data: PropTypes.data data: React.PropTypes.data
}; };
export default MetricItem; export default MetricItem;

View File

@ -5,6 +5,11 @@ import { Checkbox, FormGroup } from '@ui/components/form';
import PropTypes from '@root/prop-types'; import PropTypes from '@root/prop-types';
import forceArray from 'force-array'; import forceArray from 'force-array';
import React from 'react'; import React from 'react';
import {
DataCentersIcon,
HealthyIcon,
InstancesMultipleIcon
} from '@ui/components/icons';
import { import {
ListItem, ListItem,
@ -15,7 +20,8 @@ import {
ListItemDescription, ListItemDescription,
ListItemGroupView, ListItemGroupView,
ListItemOptions, ListItemOptions,
ListItemHeader ListItemHeader,
ListItemInfo
} from '@ui/components/list'; } from '@ui/components/list';
const StyledFormGroup = styled(FormGroup)` const StyledFormGroup = styled(FormGroup)`
@ -36,7 +42,7 @@ const ServiceItem = ({
service = {} service = {}
}) => { }) => {
const isChild = !!service.parent; const isChild = !!service.parent;
console.log('service = ', service);
const childs = forceArray(service.services).map((service) => ( const childs = forceArray(service.services).map((service) => (
<ServiceItem <ServiceItem
key={service.uuid} key={service.uuid}
@ -69,10 +75,6 @@ const ServiceItem = ({
<ListItemSubTitle>{service.instances} instances</ListItemSubTitle> <ListItemSubTitle>{service.instances} instances</ListItemSubTitle>
); );
const description = (
<ListItemDescription>Flags</ListItemDescription>
);
const onOptionsClick = (evt) => { const onOptionsClick = (evt) => {
onQuickActions(evt, service.uuid); onQuickActions(evt, service.uuid);
}; };
@ -81,12 +83,20 @@ const ServiceItem = ({
<ListItemHeader> <ListItemHeader>
<ListItemMeta> <ListItemMeta>
{title} {title}
{subtitle} <ListItemDescription>
{description} <ListItemInfo
icon={<InstancesMultipleIcon />}
iconPosition='top'
label={`${service.instances} ${service.instances > 1 ?
'instances' : 'instance' }`}
/>
<ListItemInfo
icon={<DataCentersIcon />}
label={service.datacenters[0].id}
/>
</ListItemDescription>
</ListItemMeta> </ListItemMeta>
<ListItemOptions onClick={onOptionsClick}> <ListItemOptions onClick={onOptionsClick} />
</ListItemOptions>
</ListItemHeader> </ListItemHeader>
); );
@ -99,7 +109,12 @@ const ServiceItem = ({
<ListItemMeta> <ListItemMeta>
{isChild && title} {isChild && title}
{isChild && subtitle} {isChild && subtitle}
{description} <ListItemDescription>
<ListItemInfo
icon={<HealthyIcon />}
label='Healthy'
/>
</ListItemDescription>
</ListItemMeta> </ListItemMeta>
<ItemMetricGroup <ItemMetricGroup
datasets={service.metrics} datasets={service.metrics}

View File

@ -9,6 +9,7 @@ import moment from 'moment';
const account = (state) => get(state, 'account.data', {}); const account = (state) => get(state, 'account.data', {});
const accountUi = (state) => get(state, 'account.ui', {}); const accountUi = (state) => get(state, 'account.ui', {});
const datacenters = (state) => get(state, 'datacenters.data', {});
const orgUiSections = (state) => get(state, 'orgs.ui.sections', []); const orgUiSections = (state) => get(state, 'orgs.ui.sections', []);
const projectUiSections = (state) => get(state, 'projects.ui.sections', []); const projectUiSections = (state) => get(state, 'projects.ui.sections', []);
const serviceUiTooltip = (state) => get(state, 'services.ui.tooltip', []); const serviceUiTooltip = (state) => get(state, 'services.ui.tooltip', []);
@ -267,8 +268,9 @@ const datasets = (
}); });
const servicesByProjectId = (projectId, metricOptions) => createSelector( const servicesByProjectId = (projectId, metricOptions) => createSelector(
[services, projectById(projectId), collapsedServices, metricsData, metricsUI], [services, projectById(projectId), collapsedServices,
(services, project, collapsed, metrics, metricsUI) => instances, datacenters, metricsData, metricsUI],
(services, project, collapsed, instances, datacenters, metrics, metricsUI) =>
services.filter((s) => s.project === project.uuid) services.filter((s) => s.project === project.uuid)
.map((service) => ({ .map((service) => ({
...service, ...service,
@ -278,6 +280,14 @@ const servicesByProjectId = (projectId, metricOptions) => createSelector(
.map((service) => ({ .map((service) => ({
...service, ...service,
metrics: datasets(metrics, service.metrics, metricsUI, metricOptions), metrics: datasets(metrics, service.metrics, metricsUI, metricOptions),
datacenters: instances.reduce((acc, instance) => {
if(instance.service === service.uuid) {
acc.push(instance);
}
return acc;
}, []).map((instance) =>
// TODO ensure uniqueness here
find(datacenters, ['uuid', instance.datacenter])),
collapsed: isCollapsed(collapsed, service.uuid), collapsed: isCollapsed(collapsed, service.uuid),
services: service.services.map((service) => ({ services: service.services.map((service) => ({
...service, ...service,

View File

@ -9,6 +9,7 @@ const style = css`
${is('secondary')` ${is('secondary')`
color: ${colors.base.white}; color: ${colors.base.white};
text-decoration: none;
`} `}
`; `;

View File

@ -0,0 +1,9 @@
import { Baseline } from '../../shared/composers';
// eslint-disable-next-line no-unused-vars
import React from 'react';
import DataCentersIcon from './svg/data-centers.svg';
export default Baseline(
DataCentersIcon
);

View File

@ -1,4 +1,5 @@
export { default as CloseIcon } from './close'; export { default as CloseIcon } from './close';
export { default as DataCentersIcon } from './data-centers';
export { default as HealthyIcon } from './healthy'; export { default as HealthyIcon } from './healthy';
export { default as HeartIcon } from './heart'; export { default as HeartIcon } from './heart';
export { default as InputConfirmIcon } from './input-confirm'; export { default as InputConfirmIcon } from './input-confirm';

View File

@ -8,6 +8,7 @@ import ListItemOutlet from './outlet';
import ListItemSubTitle from './subtitle'; import ListItemSubTitle from './subtitle';
import ListItemTitle from './title'; import ListItemTitle from './title';
import ListItemView from './view'; import ListItemView from './view';
import ListItemInfo from './info';
export { export {
ListItemDescription, ListItemDescription,
@ -19,5 +20,6 @@ export {
ListItemOutlet, ListItemOutlet,
ListItemSubTitle, ListItemSubTitle,
ListItemTitle, ListItemTitle,
ListItemView ListItemView,
ListItemInfo
}; };

View File

@ -0,0 +1,43 @@
import React from 'react';
import styled from 'styled-components';
import { unitcalc } from '../../shared/functions';
import { P } from '../base-elements';
const StyledContainer = styled.div`
display: inline-block;
margin: 0 ${unitcalc(2)};
`;
const StyledIcon = styled.div`
display: inline-block;
margin-right: ${unitcalc(1)};
vertical-align: ${props =>
props.iconPosition ?
props.iconPosition : 'text-top'};
`;
const StyledP = styled(P)`
display: inline-block;
margin: 0;
`;
const Info = ({
icon,
iconPosition,
label
}) => (
<StyledContainer>
<StyledIcon iconPosition={iconPosition}>
{icon}
</StyledIcon>
<StyledP>{label}</StyledP>
</StyledContainer>
);
Info.propTypes = {
icon: React.PropTypes.node,
iconPosition: React.PropTypes.string,
label: React.PropTypes.string
};
export default Info;

View File

@ -12,11 +12,12 @@ const Nav = styled.nav`
box-sizing: border-box; box-sizing: border-box;
${is('fromHeader')` ${is('fromHeader')`
border-left-color: ${colors.base.primary}; border-left-color: ${colors.base.primaryDesaturatedActive};
`}; `};
`; `;
const StyledButton = styled(Button)` const StyledButton = styled(Button)`
position: relative;
border-width: 0; border-width: 0;
box-shadow: none; box-shadow: none;
width: 100%; width: 100%;
@ -46,8 +47,20 @@ const StyledButton = styled(Button)`
} }
`; `;
const StyledContainer = styled.div`
position: absolute;
left: 50%;
`;
const StyledCircle = styled.div`
margin: 0 0 2px -2px;
border-radius: 50%;
background-color: ${colors.base.white};
width: 4px;
height: 4px;
`;
const Options = ({ const Options = ({
children,
...props ...props
}) => { }) => {
const render = ({ const render = ({
@ -61,7 +74,11 @@ const Options = ({
rect rect
{...props} {...props}
> >
{children} <StyledContainer>
<StyledCircle />
<StyledCircle />
<StyledCircle />
</StyledContainer>
</StyledButton> </StyledButton>
</Nav> </Nav>
); );
@ -74,7 +91,6 @@ const Options = ({
}; };
Options.propTypes = { Options.propTypes = {
children: React.PropTypes.node,
collapsed: React.PropTypes.bool, collapsed: React.PropTypes.bool,
fromHeader: React.PropTypes.bool fromHeader: React.PropTypes.bool
}; };

View File

@ -1,5 +1,5 @@
import { Subscriber } from 'react-broadcast'; import { Subscriber } from 'react-broadcast';
import { is } from '../../shared/functions'; import { is, remcalc } from '../../shared/functions';
import { Baseline } from '../../shared/composers'; import { Baseline } from '../../shared/composers';
import Column from '../column'; import Column from '../column';
import styled from 'styled-components'; import styled from 'styled-components';
@ -7,6 +7,9 @@ import React from 'react';
const StyledColumn = styled(Column)` const StyledColumn = styled(Column)`
display: block; display: block;
min-width: auto;
max-width: ${remcalc(480)};
margin-left: auto;
${is('collapsed')` ${is('collapsed')`
display: none; display: none;

View File

@ -5,6 +5,7 @@ import styled from 'styled-components';
import React from 'react'; import React from 'react';
const OuterBox = styled.div` const OuterBox = styled.div`
box-sizing: border-box;
height: ${remcalc(53)}; height: ${remcalc(53)};
padding: ${remcalc(8)} ${remcalc(12)}; padding: ${remcalc(8)} ${remcalc(12)};
border-bottom: ${remcalc(1)} solid ${colors.seperator}; border-bottom: ${remcalc(1)} solid ${colors.seperator};