feat(joyent-ui-toolkit, joyent-cp-frontend): Display transitional service statuses

This commit is contained in:
JUDIT GRESKOVITS 2017-07-07 18:04:01 +01:00 committed by Sérgio Ramos
parent 5ccd873a54
commit 06ab07a966
11 changed files with 137 additions and 65 deletions

View File

@ -1,42 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import remcalc from 'remcalc';
import { P } from 'joyent-ui-toolkit';
const StyledStatus = P.extend`
margin: 0;
font-size: ${remcalc(13)};
line-height: ${remcalc(13)};
`;
const StyledStatusContainer = styled.div`
margin: ${remcalc(6)} 0 ${remcalc(12)} 0;
height: ${remcalc(54)}
`;
const InstanceStatuses = ({ instanceStatuses }) => {
const statuses = instanceStatuses.map(instanceStatus => {
const { status, count } = instanceStatus;
return (
<StyledStatus>
{`${count}
${count > 1 ? 'instances' : 'instance'}
${status.toLowerCase()}`}
</StyledStatus>
);
});
return (
<StyledStatusContainer>
{statuses}
</StyledStatusContainer>
);
};
InstanceStatuses.propTypes = {
instanceStatuses: PropTypes.array.isRequired
};
export default InstanceStatuses;

View File

@ -18,7 +18,7 @@ import {
import { InstancesIcon, HealthyIcon, P } from 'joyent-ui-toolkit';
import InstanceStatuses from './instance-statuses';
import Status from './status';
const StyledCardHeader = styled(CardHeader)`
position: relative;
@ -105,7 +105,7 @@ const ServiceListItem = ({
{isChild && title}
{isChild && subtitle}
<CardDescription>
<InstanceStatuses instanceStatuses={service.instanceStatuses} />
<Status service={service} />
<CardInfo
icon={<HealthyIcon />}
iconPosition="left"

View File

@ -0,0 +1,61 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import remcalc from 'remcalc';
import { StatusLoader, P } from 'joyent-ui-toolkit';
const StyledStatusContainer = styled.div`
display: inline-block;
margin: 0;
height: ${remcalc(54)};
width: ${remcalc(200)};
`;
const StyledStatus = P.extend`
margin: 0;
font-size: ${remcalc(13)};
line-height: ${remcalc(13)};
`;
const StyledTransitionalStatus = StyledStatus.extend`
display: inline-block;
margin-left: ${remcalc(6)};
text-transform: capitalize;
`;
const ServiceStatus = ({ service }) => {
const getInstanceStatuses = (instanceStatuses) =>
instanceStatuses.map((instanceStatus, index) => {
const { status, count } = instanceStatus;
return (
<StyledStatus key={index}>
{`${count}
${count > 1 ? 'instances' : 'instance'}
${status.toLowerCase()}`}
</StyledStatus>
);
});
return service.transitionalStatus
? (
<StyledStatusContainer>
<StatusLoader />
<StyledTransitionalStatus>
{ service.status ? service.status.toLowerCase() : '' }
</StyledTransitionalStatus>
</StyledStatusContainer>
)
: (
<StyledStatusContainer>
{getInstanceStatuses(service.instanceStatuses)}
</StyledStatusContainer>
);
};
ServiceStatus.propTypes = {
service: PropTypes.object.isRequired
};
export default ServiceStatus;

View File

@ -1,7 +1,8 @@
#import "./ServiceInfo.gql"
mutation DeleteServices($ids: [ID]!) {
deleteServices(ids: $ids) {
id
slug
...ServiceInfo
instances {
id
status

View File

@ -1,6 +1,7 @@
#import "./ServiceInfo.gql"
mutation RestartServices($ids: [ID]!) {
restartServices(ids: $ids) {
id
slug
...ServiceInfo
}
}

View File

@ -1,7 +1,8 @@
#import "./ServiceInfo.gql"
mutation StartServices($ids: [ID]!) {
startServices(ids: $ids) {
id
slug
...ServiceInfo
instances {
id
status

View File

@ -1,7 +1,8 @@
#import "./ServiceInfo.gql"
mutation StopServices($ids: [ID]!) {
stopServices(ids: $ids) {
id
slug
...ServiceInfo
instances {
id
status

View File

@ -68,7 +68,16 @@ const activeInstanceStatuses = [
'INCOMPLETE'
];
const transitionalServiceStatuses = [
'PROVISIONING',
'SCALING',
'STOPPING',
'DELETING',
'RESTARTING'
];
const getInstanceStatuses = service => {
const instanceStatuses = service.instances.reduce((statuses, instance) => {
// if (instance.status !== 'RUNNING') {
if (statuses[instance.status]) {
@ -97,19 +106,18 @@ const getInstancesActive = instanceStatuses => {
};
const getService = (service, index) => {
const statuses = getInstanceStatuses(service);
const instancesActive = getInstancesActive(statuses);
const instanceStatuses = statuses.length === 1 &&
statuses[0].status === 'RUNNING'
? []
: statuses;
return {
index,
...service,
instanceStatuses,
instancesActive,
isConsul: service.slug === 'consul'
};
const instanceStatuses = getInstanceStatuses(service);
const instancesActive = getInstancesActive(instanceStatuses);
const transitionalStatus = transitionalServiceStatuses.indexOf(service.status) !== -1;
return ({
index,
...service,
instanceStatuses,
instancesActive,
transitionalStatus,
isConsul: service.slug === 'consul'
});
};
const processServices = services => {

View File

@ -17,6 +17,7 @@ export { default as CloseButton } from './close-button';
export { default as IconButton } from './icon-button';
export { Tooltip, TooltipButton, TooltipDivider } from './tooltip';
export { Dropdown } from './dropdown';
export { default as StatusLoader } from './status-loader';
export {
default as Progressbar,

View File

@ -0,0 +1,35 @@
import React, { Component } from 'react';
import styled, { keyframes } from 'styled-components';
const animationName = keyframes`
0% {
opacity: 1;
stroke-width: 2;
}
100% {
opacity: 0.25;
stroke-width: 0;
}
`;
const StyledFirstRect = styled.rect`
fill: ${props => props.theme.primary};
stroke: ${props => props.theme.primary};
animation: ${animationName} 1.5s ease-out 0s infinite;
`;
const StyledSecondRect = StyledFirstRect.extend`
animation-delay: 0.5s;
`;
const StyledThirdRect = StyledFirstRect.extend`
animation-delay: 1s;
`;
export default () => (
<svg width='28' height='10'>
<StyledFirstRect x='2' y='2' width='6' height='6' />
<StyledSecondRect x='11' y='2' width='6' height='6' />
<StyledThirdRect x='20' y='2' width='6' height='6' />
</svg>
);

View File

@ -0,0 +1,5 @@
```
const SectionLoader = require('./index').default
<SectionLoader />
```