import React, { Component } from 'react';
import { compose, graphql } from 'react-apollo';
import { connect } from 'react-redux';
import styled from 'styled-components';
import forceArray from 'force-array';
import sortBy from 'lodash.sortby';
import ServicesQuery from '@graphql/Services.gql';
import ServicesRestartMutation from '@graphql/ServicesRestartMutation.gql';
import ServicesStopMutation from '@graphql/ServicesStopMutation.gql';
import ServicesStartMutation from '@graphql/ServicesStartMutation.gql';
import { processServices } from '@root/state/selectors';
import { toggleServicesQuickActions } from '@root/state/actions';
import { LayoutContainer } from '@components/layout';
import { Loader, ErrorMessage } from '@components/messaging';
import { ServiceListItem } from '@components/services';
import { ServicesQuickActions } from '@components/services';
import { withNotFound, GqlPaths } from '@containers/navigation';
const StyledContainer = styled.div`
position: relative;
`;
class ServiceList extends Component {
constructor(props) {
super(props);
this.state = {
errors: {}
};
}
ref(name) {
this._refs = this._refs || {};
return el => {
this._refs[name] = el;
};
}
render() {
const {
deploymentGroup,
services,
loading,
error,
servicesQuickActions,
toggleServicesQuickActions,
url,
push,
restartServices,
stopServices,
startServices,
location
} = this.props;
if (loading && !forceArray(services).length) {
return (
);
}
if (error) {
return (
);
}
if (
deploymentGroup &&
deploymentGroup.status === 'PROVISIONING' &&
!forceArray(services).length
) {
return (
);
}
const handleQuickActionsClick = (evt, service) => {
const list = this._refs.container;
const listRect = list.getBoundingClientRect();
const button = evt.currentTarget;
const buttonRect = button.getBoundingClientRect();
const position = {
left:
buttonRect.left -
listRect.left +
(buttonRect.right - buttonRect.left) / 2,
top: buttonRect.bottom - listRect.top
};
toggleServicesQuickActions({
service,
position
});
};
const handleRestartClick = (evt, service) => {
this.setState({ errors: {} });
restartServices(service.id).catch(err => {
this.setState({ errors: { restart: err } });
});
};
const handleStopClick = (evt, service) => {
this.setState({ errors: {} });
stopServices(service.id).catch(err => {
this.setState({ errors: { stop: err } });
});
};
const handleStartClick = (evt, service) => {
this.setState({ errors: {} });
startServices(service.id).catch(err => {
this.setState({ errors: { start: err } });
});
};
const handleScaleClick = (evt, service) => {
toggleServicesQuickActions({ show: false });
push(`${url}/${service.slug}/scale`);
};
const handleDeleteClick = (evt, service) => {
toggleServicesQuickActions({ show: false });
push(`${url}/${service.slug}/delete`);
};
const handleQuickActionsBlur = o => {
toggleServicesQuickActions({ show: false });
};
let renderedError = null;
if (
this.state.errors.stop ||
this.state.errors.start ||
this.state.errors.restart
) {
const message = this.state.errors.stop
? 'An error occured while attempting to stop your service.'
: this.state.errors.start
? 'An error occured while attempting to start your service.'
: this.state.errors.restart
? 'An error occured while attempting to restart your service.'
: '';
renderedError = (
);
}
const serviceList = sortBy(services, ['slug']).map(service => {
return (
);
});
return (
{renderedError}
{serviceList}
);
}
}
const mapStateToProps = (state, ownProps) => ({
servicesQuickActions: state.ui.services.quickActions,
url: ownProps.match.url.replace(/\/$/, ''),
push: ownProps.history.push
});
const mapDispatchToProps = dispatch => ({
toggleServicesQuickActions: data => dispatch(toggleServicesQuickActions(data))
});
const UiConnect = connect(mapStateToProps, mapDispatchToProps);
const ServicesGql = graphql(ServicesQuery, {
options(props) {
return {
pollInterval: 1000,
variables: {
deploymentGroupSlug: props.match.params.deploymentGroup
}
};
},
props: ({ data: { deploymentGroup, loading, error }}) => ({
deploymentGroup,
services: deploymentGroup
? processServices(deploymentGroup.services, null)
: null,
loading,
error
})
});
const ServicesRestartGql = graphql(ServicesRestartMutation, {
props: ({ mutate }) => ({
restartServices: serviceId => mutate({ variables: { ids: [serviceId] } })
})
});
const ServicesStopGql = graphql(ServicesStopMutation, {
props: ({ mutate }) => ({
stopServices: serviceId => mutate({ variables: { ids: [serviceId] } })
})
});
const ServicesStartGql = graphql(ServicesStartMutation, {
props: ({ mutate }) => ({
startServices: serviceId => mutate({ variables: { ids: [serviceId] } })
})
});
const ServiceListWithData = compose(
ServicesGql,
ServicesRestartGql,
ServicesStopGql,
ServicesStartGql,
ServicesGql,
UiConnect,
withNotFound([ GqlPaths.DEPLOYMENT_GROUP ])
)(ServiceList);
export default ServiceListWithData;