diff --git a/packages/cp-frontend/src/components/deployment-groups/index.js b/packages/cp-frontend/src/components/deployment-groups/index.js deleted file mode 100644 index 1af0beb5..00000000 --- a/packages/cp-frontend/src/components/deployment-groups/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as DeploymentGroupsLoading } from './loading'; diff --git a/packages/cp-frontend/src/components/deployment-groups/loading.js b/packages/cp-frontend/src/components/deployment-groups/loading.js deleted file mode 100644 index 057a1528..00000000 --- a/packages/cp-frontend/src/components/deployment-groups/loading.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { Col, Row } from 'react-styled-flexboxgrid'; -import { Dots2 } from 'styled-text-spinners'; - -const LoadingRow = Row.extend` - flex: 1 1 auto; -`; - -export default () => - - - - - ; diff --git a/packages/cp-frontend/src/components/layout/container.js b/packages/cp-frontend/src/components/layout/container.js index f0099fe0..1cab6c3b 100644 --- a/packages/cp-frontend/src/components/layout/container.js +++ b/packages/cp-frontend/src/components/layout/container.js @@ -7,13 +7,13 @@ export default Grid.extend` ${isNot('plain')` flex: 1 1 auto; - display: flex; + display: block; flex-flow: column; `}; ${is('center')` display: flex; - flex-direction: row; + flex-direction: column; flex-wrap: nowrap; justify-content: center; align-content: center; diff --git a/packages/cp-frontend/src/components/manifest/edit-or-create.js b/packages/cp-frontend/src/components/manifest/edit-or-create.js index 0c7d15ce..068867ea 100644 --- a/packages/cp-frontend/src/components/manifest/edit-or-create.js +++ b/packages/cp-frontend/src/components/manifest/edit-or-create.js @@ -3,11 +3,12 @@ import { Field } from 'redux-form'; import styled from 'styled-components'; import SimpleTable from 'react-simple-table'; import { Row, Col } from 'react-styled-flexboxgrid'; -import { Dots2 } from 'styled-text-spinners'; import Bundle from 'react-bundle'; import remcalc from 'remcalc'; import forceArray from 'force-array'; +import { Loader } from '@components/messaging'; + import { FormGroup, FormMeta, @@ -18,7 +19,8 @@ import { ProgressbarItem, ProgressbarButton, H3, - typography + typography, + StatusLoader } from 'joyent-ui-toolkit'; const Dl = styled.dl` @@ -88,7 +90,7 @@ class ManifestEditorBundle extends Component { }, 80); } - return ; + return ; } render() { if (!this.state.ManifestEditor) { @@ -161,7 +163,7 @@ export const Manifest = ({ disabled={!(dirty || !loading || defaultValue.length)} type="submit" > - Environment + {loading ? : 'Environment'} ; @@ -180,7 +182,7 @@ const Filename = ({ name, onRemoveFile }) => export const Files = ({ loading, files, onRemoveFile }) => { if (loading) { - return null; + return ; } const _files = files.map(({ id, name, value }) => @@ -229,12 +231,18 @@ export const Environment = ({ disabled={!(dirty || !loading || defaultValue.length)} type="submit" > - {loading ? : 'Review'} + {loading ? : 'Review'} ; -export const Review = ({ handleSubmit, onCancel, dirty, ...state }) => { +export const Review = ({ + handleSubmit, + onCancel, + dirty, + loading, + ...state +}) => { const serviceList = forceArray(state.services).map(({ name, config }) =>
@@ -274,11 +282,11 @@ export const Review = ({ handleSubmit, onCancel, dirty, ...state }) => {
{serviceList} - -
diff --git a/packages/cp-frontend/src/components/messaging/loader.js b/packages/cp-frontend/src/components/messaging/loader.js index ff0664d1..917cb8f3 100644 --- a/packages/cp-frontend/src/components/messaging/loader.js +++ b/packages/cp-frontend/src/components/messaging/loader.js @@ -7,10 +7,11 @@ const Container = styled.div` display: flex; flex-direction: column; flex-wrap: nowrap; - justify-content: flex-start; + justify-content: center; align-content: center; align-items: center; - flex: 1 1 auto; + + flex: 1 0 auto; align-self: stretch; `; @@ -23,6 +24,7 @@ const Msg = P.extend` flex: 0 0 auto; align-self: stretch; text-align: center; + margin-bottom: 0; `; export default ({ msg }) => diff --git a/packages/cp-frontend/src/components/navigation/index.js b/packages/cp-frontend/src/components/navigation/index.js index d5cc1a4d..a69ba5ad 100644 --- a/packages/cp-frontend/src/components/navigation/index.js +++ b/packages/cp-frontend/src/components/navigation/index.js @@ -1,3 +1,4 @@ export { default as Breadcrumb } from './breadcrumb'; export { default as Menu } from './menu'; export { default as Header } from './header'; +export { default as Title } from './title'; diff --git a/packages/cp-frontend/src/components/navigation/title.js b/packages/cp-frontend/src/components/navigation/title.js new file mode 100644 index 00000000..923a4aa6 --- /dev/null +++ b/packages/cp-frontend/src/components/navigation/title.js @@ -0,0 +1,8 @@ +import { H2 } from 'joyent-ui-toolkit'; +import remcalc from 'remcalc'; + +export default H2.extend` + margin-top: ${remcalc(2)}; + flex: 0 0 auto; + align-self: stretch; +`; diff --git a/packages/cp-frontend/src/components/services/list-item.js b/packages/cp-frontend/src/components/services/list-item.js index 38ed6855..c230036b 100644 --- a/packages/cp-frontend/src/components/services/list-item.js +++ b/packages/cp-frontend/src/components/services/list-item.js @@ -41,7 +41,7 @@ const ServiceListItem = ({ onQuickActionsClick(evt, service); }; - const children = forceArray(service.children); + const children = sortBy(forceArray(service.children), ['slug']); const isServiceInactive = service.status && service.status !== 'ACTIVE'; const to = `/deployment-groups/${deploymentGroup}/services/${service.slug}`; @@ -49,7 +49,7 @@ const ServiceListItem = ({ ? children.reduce((count, child) => count + child.instances.length, 0) : service.instances.length; - const childrenItems = sortBy(children, ['slug']).map(service => + const childrenItems = children.map(service => ; - } - if (this.props.error) { + const { loading, error } = this.props; + + if (loading) { return ( - + + + + ); + } + + if (error) { + return ( + + + ); } diff --git a/packages/cp-frontend/src/containers/deployment-groups/create.js b/packages/cp-frontend/src/containers/deployment-groups/create.js index e78e3185..894f8985 100644 --- a/packages/cp-frontend/src/containers/deployment-groups/create.js +++ b/packages/cp-frontend/src/containers/deployment-groups/create.js @@ -3,32 +3,11 @@ import React from 'react'; import ManifestEditOrCreate from '@containers/manifest/edit-or-create'; import { Progress } from '@components/manifest/edit-or-create'; import { LayoutContainer } from '@components/layout'; -import { DeploymentGroupsLoading } from '@components/deployment-groups'; -import { H2 } from 'joyent-ui-toolkit'; +import { Title } from '@components/navigation'; -export default ({ - loading, - error, - manifest = '', - deploymentGroup = null, - match -}) => { - const stage = match.params.stage; - - return ( - -

Creating deployment group

- {loading && } - {error && - - {error.toString()} - } - - -
- ); -}; +export default ({ match }) => + + Creating deployment group + + + ; diff --git a/packages/cp-frontend/src/containers/deployment-groups/import.js b/packages/cp-frontend/src/containers/deployment-groups/import.js index 3d25b363..cbd5d2dc 100644 --- a/packages/cp-frontend/src/containers/deployment-groups/import.js +++ b/packages/cp-frontend/src/containers/deployment-groups/import.js @@ -5,15 +5,14 @@ import intercept from 'apr-intercept'; import DeploymentGroupImportMutation from '@graphql/DeploymentGroupImport.gql'; import { LayoutContainer } from '@components/layout'; -import { DeploymentGroupsLoading } from '@components/deployment-groups'; -import { H2 } from 'joyent-ui-toolkit'; +import { Title } from '@components/navigation'; +import { ErrorMessage, Loader } from '@components/messaging'; class DeploymentGroupImport extends Component { constructor() { super(); this.state = { - loading: true, error: false }; @@ -40,14 +39,21 @@ class DeploymentGroupImport extends Component { render() { const { loading, error } = this.state; + const _title = Importing deployment group; + + if (error) { + return ( + + {_title} + + + ); + } + return ( - -

Importing deployment group

- {loading && } - {error && - - {error.toString()} - } + + {_title} + ); } diff --git a/packages/cp-frontend/src/containers/deployment-groups/list.js b/packages/cp-frontend/src/containers/deployment-groups/list.js index 8aa1c55f..877a4528 100644 --- a/packages/cp-frontend/src/containers/deployment-groups/list.js +++ b/packages/cp-frontend/src/containers/deployment-groups/list.js @@ -8,16 +8,12 @@ import forceArray from 'force-array'; import remcalc from 'remcalc'; import { LayoutContainer } from '@components/layout'; -import { ErrorMessage } from '@components/messaging'; -import { DeploymentGroupsLoading } from '@components/deployment-groups'; +import { Title } from '@components/navigation'; +import { ErrorMessage, Loader } from '@components/messaging'; import DeploymentGroupsQuery from '@graphql/DeploymentGroups.gql'; import DeploymentGroupsImportableQuery from '@graphql/DeploymentGroupsImportable.gql'; import { H2, H3, Small, IconButton, BinIcon } from 'joyent-ui-toolkit'; -const Title = H2.extend` - margin-top: ${remcalc(2)}; -`; - const DGsRows = Row.extend` margin-top: ${remcalc(-7)}; `; @@ -109,14 +105,25 @@ const DeploymentGroupList = ({ error, match }) => { - const _loading = !loading ? null : ; + const _title = Deployment groups; - // todo improve this error message style according to new designs - const _error = !error - ? null - : + if (loading) { + return ( + + {_title} + + + ); + } + + if (error) { + return ( + + {_title} - ; +
+ ); + } const groups = forceArray(deploymentGroups).map(({ slug, name }) => @@ -159,9 +166,7 @@ const DeploymentGroupList = ({ return ( - Deployment groups - {_loading} - {_error} + {_title} {groups} {create} diff --git a/packages/cp-frontend/src/containers/instances/list.js b/packages/cp-frontend/src/containers/instances/list.js index 59943de6..0a432257 100644 --- a/packages/cp-frontend/src/containers/instances/list.js +++ b/packages/cp-frontend/src/containers/instances/list.js @@ -1,52 +1,63 @@ import React, { Component } from 'react'; -// Import PropTypes from 'prop-types'; import { compose, graphql } from 'react-apollo'; import InstancesQuery from '@graphql/Instances.gql'; import { Row } from 'react-styled-flexboxgrid'; import remcalc from 'remcalc'; +import forceArray from 'force-array'; +import sortBy from 'lodash.sortby'; import { LayoutContainer } from '@components/layout'; -import { ErrorMessage } from '@components/messaging'; +import { Title } from '@components/navigation'; +import { Loader, ErrorMessage } from '@components/messaging'; import { InstanceListItem, EmptyInstances } from '@components/instances'; -import { DeploymentGroupsLoading } from '@components/deployment-groups'; -import { H2 } from 'joyent-ui-toolkit'; -const Title = H2.extend` - margin-top: ${remcalc(2)}; -`; - -class InstanceList extends Component { - render() { - const { instances, loading, error } = this.props; - - const _loading = !loading ? null : ; - - const _error = !error - ? null - : - - ; - - const instanceList = instances - ? instances.map((instance, index) => - null} - /> - ) - : ; +const InstanceList = ({ deploymentGroup, instances = [], loading, error }) => { + const _title = Instances; + if (loading && !forceArray(instances).length) { return ( - - Instances - {_error} - {_loading} - {instanceList} + + {_title} + ); } -} + + if (error) { + return ( + + {_title} + + + ); + } + + if (deploymentGroup.status === 'PROVISIONING' && !instances.length) { + return ( + + {_title} + + + ); + } + + const instanceList = instances.map((instance, index) => + null} + /> + ); + + const _instances = !instanceList.length ? : instanceList; + + return ( + + {_title} + {_instances} + + ); +}; const InstanceListGql = graphql(InstancesQuery, { options(props) { @@ -63,18 +74,20 @@ const InstanceListGql = graphql(InstancesQuery, { }; }, props: ({ data: { deploymentGroup, loading, error } }) => ({ - instances: - deploymentGroup && deploymentGroup.services - ? deploymentGroup.services.reduce( + deploymentGroup, + instances: sortBy( + forceArray( + deploymentGroup && + forceArray(deploymentGroup.services).reduce( (instances, service) => instances.concat(service.instances), [] ) - : null, + ).filter(Boolean), + ['name'] + ), loading, error }) }); -const InstanceListWithData = compose(InstanceListGql)(InstanceList); - -export default InstanceListWithData; +export default compose(InstanceListGql)(InstanceList); diff --git a/packages/cp-frontend/src/containers/manifest/edit-or-create.js b/packages/cp-frontend/src/containers/manifest/edit-or-create.js index 6bdec156..fb9ac3f0 100644 --- a/packages/cp-frontend/src/containers/manifest/edit-or-create.js +++ b/packages/cp-frontend/src/containers/manifest/edit-or-create.js @@ -14,6 +14,7 @@ import DeploymentGroupProvisionMutation from '@graphql/DeploymentGroupProvision. import DeploymentGroupConfigQuery from '@graphql/DeploymentGroupConfig.gql'; import { client } from '@state/store'; +import { ErrorMessage } from '@components/messaging'; import { Name, Manifest, @@ -354,14 +355,10 @@ class DeploymentGroupEditOrCreate extends Component { } render() { - const { error, defaultStage, manifestStage } = this.state; + const { error, loading, defaultStage, manifestStage } = this.state; if (error) { - return ( - - {error} - - ); + return ; } const { match, create } = this.props; diff --git a/packages/cp-frontend/src/containers/manifest/index.js b/packages/cp-frontend/src/containers/manifest/index.js index 866e2572..0e158389 100644 --- a/packages/cp-frontend/src/containers/manifest/index.js +++ b/packages/cp-frontend/src/containers/manifest/index.js @@ -9,8 +9,8 @@ import DeploymentGroupBySlugQuery from '@graphql/DeploymentGroupBySlug.gql'; import ManifestEditOrCreate from '@containers/manifest/edit-or-create'; import { Progress } from '@components/manifest/edit-or-create'; import { LayoutContainer } from '@components/layout'; -import { DeploymentGroupsLoading } from '@components/deployment-groups'; -import { H2 } from 'joyent-ui-toolkit'; +import { Title } from '@components/navigation'; +import { Loader, ErrorMessage } from '@components/messaging'; const Manifest = ({ loading, @@ -21,43 +21,42 @@ const Manifest = ({ match }) => { const stage = match.params.stage; - const _loading = !loading ? null : ; - const _error = !error - ? null - : - {error.toString()} - ; + const _title = Edit Manifest; - const _view = - loading || !deploymentGroup - ? null - : ; + if (loading || !deploymentGroup) { + return ( + + {_title} + + + ); + } + + if (error) { + return ( + + {_title} + + + ); + } const _notice = - !error && - !loading && - deploymentGroup && - deploymentGroup.imported && - !manifest - ? - Since this DeploymentGroup was imported, it doesn't have the - initial manifest - + deploymentGroup && deploymentGroup.imported && !manifest + ? : null; return ( -

Edit Manifest

+ {_title} - {_error} - {_loading} {_notice} - {_view} +
); }; diff --git a/packages/cp-frontend/src/containers/navigation/header.js b/packages/cp-frontend/src/containers/navigation/header.js index 939ad7b4..0e917284 100644 --- a/packages/cp-frontend/src/containers/navigation/header.js +++ b/packages/cp-frontend/src/containers/navigation/header.js @@ -1,30 +1,17 @@ import React from 'react'; import { graphql } from 'react-apollo'; +import get from 'lodash.get'; + import PortalQuery from '@graphql/Portal.gql'; import { Header as HeaderComponent } from '@components/navigation'; -const Header = ({ - portal = { - datacenter: { - region: '' - }, - user: { - firstName: '' - } - }, - loading, - error -}) => - ; +const Header = ({ datacenter, username }) => + ; const HeaderWithData = graphql(PortalQuery, { - props: ({ data: { portal, loading, error } }) => ({ - portal, - loading, - error + props: ({ data: { portal = {} } }) => ({ + datacenter: get(portal, 'datacenter.region', ''), + username: get(portal, 'user.firstName', '') }) })(Header); diff --git a/packages/cp-frontend/src/containers/service/delete.js b/packages/cp-frontend/src/containers/service/delete.js index 37b75314..82d010be 100644 --- a/packages/cp-frontend/src/containers/service/delete.js +++ b/packages/cp-frontend/src/containers/service/delete.js @@ -9,12 +9,21 @@ import ServiceGql from './service-gql'; class ServiceDelete extends Component { render() { - if (this.props.loading) { - return ; - } - if (this.props.error) { + const { loading, error } = this.props; + + if (loading) { return ( - + + + + ); + } + + if (error) { + return ( + + + ); } @@ -56,8 +65,4 @@ const DeleteServicesGql = graphql(ServicesDeleteMutation, { }) }); -const ServiceDeleteWithData = compose(DeleteServicesGql, ServiceGql)( - ServiceDelete -); - -export default ServiceDeleteWithData; +export default compose(DeleteServicesGql, ServiceGql)(ServiceDelete); diff --git a/packages/cp-frontend/src/containers/service/scale.js b/packages/cp-frontend/src/containers/service/scale.js index af89951b..7bb5639e 100644 --- a/packages/cp-frontend/src/containers/service/scale.js +++ b/packages/cp-frontend/src/containers/service/scale.js @@ -10,13 +10,21 @@ import ServiceGql from './service-gql'; class ServiceScale extends Component { render() { - if (this.props.loading) { - return ; + const { loading, error } = this.props; + + if (loading) { + return ( + + + + ); } - if (this.props.error) { + if (error) { return ( - + + + ); } @@ -85,6 +93,4 @@ const ServiceScaleGql = graphql(ServiceScaleMutation, { }) }); -const ServiceScaleWithData = compose(ServiceScaleGql, ServiceGql)(ServiceScale); - -export default ServiceScaleWithData; +export default compose(ServiceScaleGql, ServiceGql)(ServiceScale); diff --git a/packages/cp-frontend/src/containers/services/list.js b/packages/cp-frontend/src/containers/services/list.js index 209e4dd4..81fa9b94 100644 --- a/packages/cp-frontend/src/containers/services/list.js +++ b/packages/cp-frontend/src/containers/services/list.js @@ -47,7 +47,7 @@ class ServiceList extends Component { startServices } = this.props; - if (loading) { + if (loading && !forceArray(services).length) { return ( @@ -68,7 +68,7 @@ class ServiceList extends Component { !forceArray(services).length ) { return ( - + ); diff --git a/packages/cp-frontend/src/containers/services/menu.js b/packages/cp-frontend/src/containers/services/menu.js index b2c940d7..cc5aef47 100644 --- a/packages/cp-frontend/src/containers/services/menu.js +++ b/packages/cp-frontend/src/containers/services/menu.js @@ -4,6 +4,7 @@ import { Col, Row } from 'react-styled-flexboxgrid'; import remcalc from 'remcalc'; import unitcalc from 'unitcalc'; import { LayoutContainer } from '@components/layout'; +import { Title } from '@components/navigation'; import { H2, FormGroup, Toggle, ToggleList, Legend } from 'joyent-ui-toolkit'; @@ -31,7 +32,7 @@ const ServicesMenu = ({ location, history: { push } }) => { return ( -

Services

+ Services diff --git a/packages/cp-frontend/src/containers/services/topology.js b/packages/cp-frontend/src/containers/services/topology.js index fac0a61b..8b0936dd 100644 --- a/packages/cp-frontend/src/containers/services/topology.js +++ b/packages/cp-frontend/src/containers/services/topology.js @@ -29,6 +29,7 @@ const StyledContainer = styled.div` const ServicesTopology = ({ url, push, + deploymentGroup, services, datacenter, loading, @@ -41,11 +42,13 @@ const ServicesTopology = ({ }) => { if (loading) { return ( - + ); - } else if (error) { + } + + if (error) { return ( @@ -53,6 +56,17 @@ const ServicesTopology = ({ ); } + if ( + deploymentGroup.status === 'PROVISIONING' && + !forceArray(services).length + ) { + return ( + + + + ); + } + const handleQuickActionsClick = (evt, tooltipData) => { toggleServicesQuickActions(tooltipData); }; @@ -132,7 +146,8 @@ const ServicesGql = graphql(ServicesQuery, { } }; }, - props: ({ data: { deploymentGroup, loading, error } }) => ({ + props: ({ data: { deploymentGroup = {}, loading, error } }) => ({ + deploymentGroup, services: deploymentGroup ? processServicesForTopology(deploymentGroup.services) : null, diff --git a/packages/ui-toolkit/src/modal/index.js b/packages/ui-toolkit/src/modal/index.js index 127f4761..f63117fa 100644 --- a/packages/ui-toolkit/src/modal/index.js +++ b/packages/ui-toolkit/src/modal/index.js @@ -23,8 +23,8 @@ const StyledModal = styled.div` position: absolute; left: 50%; top: 33.33%; - padding: ${remcalc(30)} ${remcalc(36)} ${remcalc(36)} ${remcalc(36)}; - background-color: ${theme.white}; + padding: ${remcalc(36)} ${remcalc(36)} ${remcalc(36)} ${remcalc(36)}; + background-color: ${props => props.theme.white}; box-shadow: ${modalShadow}; width: ${props => remcalc(props.width)};