From 06ab07a96682c041336b74bd48a7930aa4dae080 Mon Sep 17 00:00:00 2001 From: JUDIT GRESKOVITS Date: Fri, 7 Jul 2017 18:04:01 +0100 Subject: [PATCH] feat(joyent-ui-toolkit, joyent-cp-frontend): Display transitional service statuses --- .../components/services/instance-statuses.js | 42 ------------- .../src/components/services/list-item.js | 4 +- .../src/components/services/status.js | 61 +++++++++++++++++++ .../src/graphql/ServicesDeleteMutation.gql | 5 +- .../src/graphql/ServicesRestartMutation.gql | 5 +- .../src/graphql/ServicesStartMutation.gql | 5 +- .../src/graphql/ServicesStopMutation.gql | 5 +- packages/cp-frontend/src/state/selectors.js | 34 +++++++---- packages/ui-toolkit/src/index.js | 1 + .../ui-toolkit/src/status-loader/index.js | 35 +++++++++++ .../ui-toolkit/src/status-loader/usage.md | 5 ++ 11 files changed, 137 insertions(+), 65 deletions(-) delete mode 100644 packages/cp-frontend/src/components/services/instance-statuses.js create mode 100644 packages/cp-frontend/src/components/services/status.js create mode 100644 packages/ui-toolkit/src/status-loader/index.js create mode 100644 packages/ui-toolkit/src/status-loader/usage.md diff --git a/packages/cp-frontend/src/components/services/instance-statuses.js b/packages/cp-frontend/src/components/services/instance-statuses.js deleted file mode 100644 index a517d58e..00000000 --- a/packages/cp-frontend/src/components/services/instance-statuses.js +++ /dev/null @@ -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 ( - - {`${count} - ${count > 1 ? 'instances' : 'instance'} - ${status.toLowerCase()}`} - - ); - }); - - return ( - - {statuses} - - ); -}; - -InstanceStatuses.propTypes = { - instanceStatuses: PropTypes.array.isRequired -}; - -export default InstanceStatuses; diff --git a/packages/cp-frontend/src/components/services/list-item.js b/packages/cp-frontend/src/components/services/list-item.js index 088c1ab8..1c4dba0c 100644 --- a/packages/cp-frontend/src/components/services/list-item.js +++ b/packages/cp-frontend/src/components/services/list-item.js @@ -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} - + } iconPosition="left" diff --git a/packages/cp-frontend/src/components/services/status.js b/packages/cp-frontend/src/components/services/status.js new file mode 100644 index 00000000..fc713ea7 --- /dev/null +++ b/packages/cp-frontend/src/components/services/status.js @@ -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 ( + + {`${count} + ${count > 1 ? 'instances' : 'instance'} + ${status.toLowerCase()}`} + + ); + }); + + return service.transitionalStatus + ? ( + + + + { service.status ? service.status.toLowerCase() : '' } + + + ) + : ( + + {getInstanceStatuses(service.instanceStatuses)} + + ); +}; + +ServiceStatus.propTypes = { + service: PropTypes.object.isRequired +}; + +export default ServiceStatus; diff --git a/packages/cp-frontend/src/graphql/ServicesDeleteMutation.gql b/packages/cp-frontend/src/graphql/ServicesDeleteMutation.gql index b4ef3a26..6e62f6a3 100644 --- a/packages/cp-frontend/src/graphql/ServicesDeleteMutation.gql +++ b/packages/cp-frontend/src/graphql/ServicesDeleteMutation.gql @@ -1,7 +1,8 @@ +#import "./ServiceInfo.gql" + mutation DeleteServices($ids: [ID]!) { deleteServices(ids: $ids) { - id - slug + ...ServiceInfo instances { id status diff --git a/packages/cp-frontend/src/graphql/ServicesRestartMutation.gql b/packages/cp-frontend/src/graphql/ServicesRestartMutation.gql index a1d0a662..f47e2c8d 100644 --- a/packages/cp-frontend/src/graphql/ServicesRestartMutation.gql +++ b/packages/cp-frontend/src/graphql/ServicesRestartMutation.gql @@ -1,6 +1,7 @@ +#import "./ServiceInfo.gql" + mutation RestartServices($ids: [ID]!) { restartServices(ids: $ids) { - id - slug + ...ServiceInfo } } diff --git a/packages/cp-frontend/src/graphql/ServicesStartMutation.gql b/packages/cp-frontend/src/graphql/ServicesStartMutation.gql index e854e34e..31ae80a9 100644 --- a/packages/cp-frontend/src/graphql/ServicesStartMutation.gql +++ b/packages/cp-frontend/src/graphql/ServicesStartMutation.gql @@ -1,7 +1,8 @@ +#import "./ServiceInfo.gql" + mutation StartServices($ids: [ID]!) { startServices(ids: $ids) { - id - slug + ...ServiceInfo instances { id status diff --git a/packages/cp-frontend/src/graphql/ServicesStopMutation.gql b/packages/cp-frontend/src/graphql/ServicesStopMutation.gql index f2778ba7..9f4149ca 100644 --- a/packages/cp-frontend/src/graphql/ServicesStopMutation.gql +++ b/packages/cp-frontend/src/graphql/ServicesStopMutation.gql @@ -1,7 +1,8 @@ +#import "./ServiceInfo.gql" + mutation StopServices($ids: [ID]!) { stopServices(ids: $ids) { - id - slug + ...ServiceInfo instances { id status diff --git a/packages/cp-frontend/src/state/selectors.js b/packages/cp-frontend/src/state/selectors.js index 8e04b1e4..8c5c9b98 100644 --- a/packages/cp-frontend/src/state/selectors.js +++ b/packages/cp-frontend/src/state/selectors.js @@ -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 => { diff --git a/packages/ui-toolkit/src/index.js b/packages/ui-toolkit/src/index.js index 33aeab97..d939556a 100644 --- a/packages/ui-toolkit/src/index.js +++ b/packages/ui-toolkit/src/index.js @@ -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, diff --git a/packages/ui-toolkit/src/status-loader/index.js b/packages/ui-toolkit/src/status-loader/index.js new file mode 100644 index 00000000..2b4a0ea7 --- /dev/null +++ b/packages/ui-toolkit/src/status-loader/index.js @@ -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 () => ( + + + + + +); diff --git a/packages/ui-toolkit/src/status-loader/usage.md b/packages/ui-toolkit/src/status-loader/usage.md new file mode 100644 index 00000000..0a2a087e --- /dev/null +++ b/packages/ui-toolkit/src/status-loader/usage.md @@ -0,0 +1,5 @@ +``` +const SectionLoader = require('./index').default + + +```