feat(ui-toolkit, cp-frontend, cp-gql-mock-server): Display healthy / unhealthy statuses

This commit is contained in:
JUDIT GRESKOVITS 2017-07-12 14:00:54 +01:00 committed by Sérgio Ramos
parent abdd9f9f6a
commit 2a34632269
14 changed files with 74 additions and 40 deletions

View File

@ -16,7 +16,7 @@ import {
Anchor Anchor
} from 'joyent-ui-toolkit'; } from 'joyent-ui-toolkit';
import { InstancesIcon, HealthyIcon, P } from 'joyent-ui-toolkit'; import { InstancesIcon, HealthyIcon, UnhealthyIcon, P } from 'joyent-ui-toolkit';
import Status from './status'; import Status from './status';
@ -97,6 +97,20 @@ const ServiceListItem = ({
<CardOptions onClick={handleCardOptionsClick} /> <CardOptions onClick={handleCardOptionsClick} />
</StyledCardHeader>; </StyledCardHeader>;
const healthyInfo = service.instancesHealthy
? <CardInfo
icon={<HealthyIcon />}
iconPosition='left'
label='Healthy'
color='dark'
/>
: <CardInfo
icon={<UnhealthyIcon />}
iconPosition='left'
label='Unhealthy'
color='dark'
/>
const view = children const view = children
? <CardGroupView> ? <CardGroupView>
{children} {children}
@ -106,12 +120,7 @@ const ServiceListItem = ({
{isChild && subtitle} {isChild && subtitle}
<CardDescription> <CardDescription>
<Status service={service} /> <Status service={service} />
<CardInfo {healthyInfo}
icon={<HealthyIcon />}
iconPosition="left"
label="Healthy"
color="dark"
/>
</CardDescription> </CardDescription>
</CardView>; </CardView>;

View File

@ -10,6 +10,7 @@ query Instances($deploymentGroupSlug: String!, $serviceSlug: String) {
id id
name name
status status
healthy
} }
} }
} }

View File

@ -11,6 +11,7 @@ query Services($deploymentGroupSlug: String!){
instances { instances {
id id
status status
healthy
} }
} }
} }

View File

@ -6,6 +6,7 @@ mutation DeleteServices($ids: [ID]!) {
instances { instances {
id id
status status
healthy
} }
} }
} }

View File

@ -6,6 +6,7 @@ mutation StartServices($ids: [ID]!) {
instances { instances {
id id
status status
healthy
} }
} }
} }

View File

@ -6,6 +6,7 @@ mutation StopServices($ids: [ID]!) {
instances { instances {
id id
status status
healthy
} }
} }
} }

View File

@ -105,16 +105,26 @@ const getInstancesActive = instanceStatuses => {
); );
}; };
const getInstancesHealthy = instances => {
return instances.reduce(
(healthy, instance) =>
instance.healthy === 'HEALTHY' ? healthy : false,
true
);
};
const getService = (service, index) => { const getService = (service, index) => {
const instanceStatuses = getInstanceStatuses(service); const instanceStatuses = getInstanceStatuses(service);
const instancesActive = getInstancesActive(instanceStatuses); const instancesActive = getInstancesActive(instanceStatuses);
const instancesHealthy = getInstancesHealthy(service.instances);
const transitionalStatus = transitionalServiceStatuses.indexOf(service.status) !== -1; const transitionalStatus = transitionalServiceStatuses.indexOf(service.status) !== -1;
return ({ return ({
index, index,
...service, ...service,
instanceStatuses, instanceStatuses,
instancesActive, instancesActive,
instancesHealthy,
transitionalStatus, transitionalStatus,
isConsul: service.slug === 'consul' isConsul: service.slug === 'consul'
}); });

View File

@ -113,77 +113,88 @@
"name": "wordpress_01", "name": "wordpress_01",
"serviceId": "be227788-74f1-4e5b-a85f-b5c71cbae8d8", "serviceId": "be227788-74f1-4e5b-a85f-b5c71cbae8d8",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "HEALTHY"
}, },
{ {
"id": "0db6db53-de6f-4378-839e-5d5b452fbaf2", "id": "0db6db53-de6f-4378-839e-5d5b452fbaf2",
"name": "nfs_01", "name": "nfs_01",
"serviceId": "6a0eee76-c019-413b-9d5f-44712b55b993", "serviceId": "6a0eee76-c019-413b-9d5f-44712b55b993",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "HEALTHY"
}, },
{ {
"id": "250c8a6c-7d02-49a9-8abd-e1c22773041d", "id": "250c8a6c-7d02-49a9-8abd-e1c22773041d",
"name": "consul", "name": "consul",
"serviceId": "97c68055-db88-45c9-ad49-f26da4264777", "serviceId": "97c68055-db88-45c9-ad49-f26da4264777",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "UNHEALTHY"
}, },
{ {
"id": "2c921f3a-8bc3-4f57-9cd7-789ebae72061", "id": "2c921f3a-8bc3-4f57-9cd7-789ebae72061",
"name": "memcache_01", "name": "memcache_01",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c", "serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "HEALTHY"
}, },
{ {
"id": "68d3046e-8e34-4f5d-a0e5-db3795a250fd", "id": "68d3046e-8e34-4f5d-a0e5-db3795a250fd",
"name": "memcache_02", "name": "memcache_02",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c", "serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "HEALTHY"
}, },
{ {
"id": "2ea99763-3b44-4179-8393-d66d94961051", "id": "2ea99763-3b44-4179-8393-d66d94961051",
"name": "memcache_03", "name": "memcache_03",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c", "serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "HEALTHY"
}, },
{ {
"id": "25f6bc62-63b8-4959-908e-1f6d7ff6341d", "id": "25f6bc62-63b8-4959-908e-1f6d7ff6341d",
"name": "memcache_04", "name": "memcache_04",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c", "serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "HEALTHY"
}, },
{ {
"id": "8be01042-0281-4a77-a357-25979e87bf3d", "id": "8be01042-0281-4a77-a357-25979e87bf3d",
"name": "memcache_05", "name": "memcache_05",
"serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c", "serviceId": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "HEALTHY"
}, },
{ {
"id": "3d652e9d-73e8-4a6f-8171-84fa83740662", "id": "3d652e9d-73e8-4a6f-8171-84fa83740662",
"name": "nginx", "name": "nginx",
"serviceId": "081a792c-47e0-4439-924b-2efa9788ae9e", "serviceId": "081a792c-47e0-4439-924b-2efa9788ae9e",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "HEALTHY"
}, },
{ {
"id": "c3ec7633-a02b-4615-86a0-9e6faeaae94b", "id": "c3ec7633-a02b-4615-86a0-9e6faeaae94b",
"name": "percona-primary", "name": "percona-primary",
"serviceId": "9572d367-c4ae-4fb1-8ad5-f5e3830e7034", "serviceId": "9572d367-c4ae-4fb1-8ad5-f5e3830e7034",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "UNHEALTHY"
}, },
{ {
"id": "c2b5fec2-31e2-41a7-b7fc-cd0bb1822e76", "id": "c2b5fec2-31e2-41a7-b7fc-cd0bb1822e76",
"name": "percona-secondary", "name": "percona-secondary",
"serviceId": "c8411ef0-ab39-42cb-a704-d20b170eff31", "serviceId": "c8411ef0-ab39-42cb-a704-d20b170eff31",
"deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401", "deploymentGroupId": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"status": "RUNNING" "status": "RUNNING",
"healthy": "HEALTHY"
} }
] ]
} }

View File

@ -5,3 +5,4 @@ export { default as ArrowIcon } from './arrow';
export { default as TickIcon } from './tick'; export { default as TickIcon } from './tick';
export { default as InstancesIcon } from './instances'; export { default as InstancesIcon } from './instances';
export { default as HealthyIcon } from './healthy'; export { default as HealthyIcon } from './healthy';
export { default as UnhealthyIcon } from './unhealthy';

View File

@ -0,0 +1,7 @@
import Baseline from '../baseline';
// eslint-disable-next-line no-unused-vars
import React from 'react';
import UnhealthyIcon from './svg/icon_error_failure.svg';
export default Baseline(UnhealthyIcon);

View File

@ -100,5 +100,6 @@ export {
MinusIcon, MinusIcon,
ArrowIcon, ArrowIcon,
InstancesIcon, InstancesIcon,
HealthyIcon HealthyIcon,
UnhealthyIcon
} from './icons'; } from './icons';

View File

@ -14,7 +14,7 @@ import { getNodeRect, calculateLineLayout } from './functions';
const StyledSvg = Svg.extend` const StyledSvg = Svg.extend`
width: 100%; width: 100%;
height: 1400px; height: 1000px;
`; `;
/** /**
@ -194,7 +194,7 @@ class Topology extends React.Component {
return { return {
width: windowWidth - 2 * 24, width: windowWidth - 2 * 24,
height: 1400 height: 1000
}; };
} }

View File

@ -8,6 +8,7 @@ import InstancesIcon from './icon-instances.svg';
import { Point } from '../prop-types'; import { Point } from '../prop-types';
import { GraphText, GraphHealthyCircle } from './shapes'; import { GraphText, GraphHealthyCircle } from './shapes';
import HeartIcon from './icon-heart.svg'; import HeartIcon from './icon-heart.svg';
import { HealthyIcon, UnhealthyIcon } from '../../icons';
const StyledInstancesIcon = styled(InstancesIcon)` const StyledInstancesIcon = styled(InstancesIcon)`
fill: ${props => props.theme.white}; fill: ${props => props.theme.white};
@ -39,7 +40,7 @@ const GraphNodeInfo = ({ data, pos }) => {
datacenter, datacenter,
instances, instances,
instanceStatuses, instanceStatuses,
healthy, instancesHealthy,
isConsul, isConsul,
instancesActive, instancesActive,
transitionalStatus, transitionalStatus,
@ -59,11 +60,13 @@ const GraphNodeInfo = ({ data, pos }) => {
</GraphText> </GraphText>
); );
const healthy = instancesHealthy
? <HealthyIcon /> : <UnhealthyIcon />;
return ( return (
<g transform={`translate(${x}, ${y})`}> <g transform={`translate(${x}, ${y})`}>
<g transform={`translate(0, 0)`}> <g transform={`translate(0, 0)`}>
<GraphHealthyCircle cx={9} cy={9} r={9} /> { healthy }
<HeartIcon />
</g> </g>
<g transform={'translate(30, 4.5)'}> <g transform={'translate(30, 4.5)'}>
<StyledInstancesIcon consul={isConsul} active={instancesActive} /> <StyledInstancesIcon consul={isConsul} active={instancesActive} />
@ -86,14 +89,7 @@ const GraphNodeInfo = ({ data, pos }) => {
GraphNodeInfo.propTypes = { GraphNodeInfo.propTypes = {
data: PropTypes.object.isRequired, data: PropTypes.object.isRequired,
pos: Point.isRequired/*, pos: Point.isRequired
datacenter: PropTypes.string,
healthy: PropTypes.bool,
instances: PropTypes.array,
instanceStatuses: PropTypes.array,
pos: Point.isRequired,
isConsul: PropTypes.bool,
instancesActive: PropTypes.bool*/
}; };
export default Baseline(GraphNodeInfo); export default Baseline(GraphNodeInfo);

View File

@ -41,20 +41,15 @@ const createLinks = services =>
const createSimulation = (services, svgSize, animationTicks = 0) => { const createSimulation = (services, svgSize, animationTicks = 0) => {
// This is not going to work given that as well as the d3 layout stuff, other things might be at play too // This is not going to work given that as well as the d3 layout stuff, other things might be at play too
// We should pass two objects to the components - one for positioning and one for data // We should pass two objects to the components - one for positioning and one for data
console.log('createSimulation services = ', services);
console.log('createSimulation services.length = ', services.length);
const nodes = services.map((service, index) => { const nodes = services.map((service, index) => {
console.log('createSimulation services.map service.id = ', service.id);
console.log('createSimulation services.map service.connected = ', service.connected);
return ({ return ({
id: service.id, id: service.id,
index index
}) })
}); });
console.log('createSimulation nodes = ', nodes);
console.log('createSimulation nodes.length = ', nodes.length);
const links = createLinks(services); const links = createLinks(services);
console.log('createSimulation links = ', links);
const { width, height } = svgSize; const { width, height } = svgSize;
const nodeRadius = rectRadius(Constants.nodeSizeWithChildren); const nodeRadius = rectRadius(Constants.nodeSizeWithChildren);
@ -65,7 +60,6 @@ const createSimulation = (services, svgSize, animationTicks = 0) => {
.force('center', forceCenter(width / 2, height / 2)); .force('center', forceCenter(width / 2, height / 2));
forcePlayAnimation(simulation, animationTicks); forcePlayAnimation(simulation, animationTicks);
console.log('createSimulation nodes = ', nodes);
return { return {
nodes, nodes,