feat(ui-toolkit, cp-frontend, cp-gql-mock-server): Display healthy / unhealthy statuses
This commit is contained in:
parent
abdd9f9f6a
commit
2a34632269
@ -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>;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ query Instances($deploymentGroupSlug: String!, $serviceSlug: String) {
|
|||||||
id
|
id
|
||||||
name
|
name
|
||||||
status
|
status
|
||||||
|
healthy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ query Services($deploymentGroupSlug: String!){
|
|||||||
instances {
|
instances {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
|
healthy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ mutation DeleteServices($ids: [ID]!) {
|
|||||||
instances {
|
instances {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
|
healthy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ mutation StartServices($ids: [ID]!) {
|
|||||||
instances {
|
instances {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
|
healthy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ mutation StopServices($ids: [ID]!) {
|
|||||||
instances {
|
instances {
|
||||||
id
|
id
|
||||||
status
|
status
|
||||||
|
healthy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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'
|
||||||
});
|
});
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -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';
|
||||||
|
7
packages/ui-toolkit/src/icons/unhealthy.js
Normal file
7
packages/ui-toolkit/src/icons/unhealthy.js
Normal 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);
|
@ -100,5 +100,6 @@ export {
|
|||||||
MinusIcon,
|
MinusIcon,
|
||||||
ArrowIcon,
|
ArrowIcon,
|
||||||
InstancesIcon,
|
InstancesIcon,
|
||||||
HealthyIcon
|
HealthyIcon,
|
||||||
|
UnhealthyIcon
|
||||||
} from './icons';
|
} from './icons';
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user