mirror of
https://github.com/yldio/copilot.git
synced 2024-11-28 06:00:06 +02:00
feat: number input and mutations for restart, stop and start
This commit is contained in:
parent
0623c06fc7
commit
7e359e5836
@ -38,3 +38,5 @@ Gruntfile.js
|
|||||||
# misc
|
# misc
|
||||||
*.gz
|
*.gz
|
||||||
*.md
|
*.md
|
||||||
|
|
||||||
|
!nyc/node_modules/istanbul-reports/lib/html/assets
|
||||||
|
@ -4,32 +4,44 @@ import styled from 'styled-components';
|
|||||||
import unitcalc from 'unitcalc';
|
import unitcalc from 'unitcalc';
|
||||||
|
|
||||||
import { H2, P, Button } from 'joyent-ui-toolkit';
|
import { H2, P, Button } from 'joyent-ui-toolkit';
|
||||||
import { FormGroup, Input, NumberInput } from 'joyent-ui-toolkit';
|
import {
|
||||||
|
FormGroup,
|
||||||
|
NumberInput,
|
||||||
|
NumberInputNormalize,
|
||||||
|
FormMeta
|
||||||
|
} from 'joyent-ui-toolkit';
|
||||||
|
|
||||||
const StyledH2 = styled(H2)`
|
const StyledH2 = styled(H2)`
|
||||||
margin: 0 0 ${unitcalc(2)} 0;
|
margin: 0 0 ${unitcalc(2)} 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ServiceScale = ({ service, onConfirmClick, onCancelClick }) => {
|
const ServiceScale = ({
|
||||||
const handleScaleClick = () => {
|
service,
|
||||||
onConfirmClick(2);
|
handleSubmit,
|
||||||
};
|
onCancelClick,
|
||||||
return (
|
invalid,
|
||||||
<div>
|
pristine
|
||||||
|
}) =>
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
<StyledH2>Scaling a service: <br />{service.name}</StyledH2>
|
<StyledH2>Scaling a service: <br />{service.name}</StyledH2>
|
||||||
<P>Choose how many instances of a service you want to have running.</P>
|
<P>Choose how many instances of a service you want to have running.</P>
|
||||||
<form onSubmit={() => {}}>
|
<FormGroup
|
||||||
<NumberInput />
|
name="replicas"
|
||||||
|
normalize={NumberInputNormalize({ minValue: 1 })}
|
||||||
|
reduxForm
|
||||||
|
>
|
||||||
|
<FormMeta />
|
||||||
|
<NumberInput minValue={1} />
|
||||||
|
</FormGroup>
|
||||||
<Button secondary onClick={onCancelClick}>Cancel</Button>
|
<Button secondary onClick={onCancelClick}>Cancel</Button>
|
||||||
<Button secondary onClick={handleScaleClick}>Scale</Button>
|
<Button type="submit" disabled={pristine || invalid} secondary>
|
||||||
</form>
|
Scale
|
||||||
</div>
|
</Button>
|
||||||
);
|
</form>;
|
||||||
};
|
|
||||||
|
|
||||||
ServiceScale.propTypes = {
|
ServiceScale.propTypes = {
|
||||||
service: PropTypes.object,
|
service: PropTypes.object,
|
||||||
onScaleClick: PropTypes.func,
|
onSubmitClick: PropTypes.func,
|
||||||
onCancelClick: PropTypes.func
|
onCancelClick: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ const ServiceListItem = ({
|
|||||||
const subtitle = <CardSubTitle>{service.instances} instances</CardSubTitle>;
|
const subtitle = <CardSubTitle>{service.instances} instances</CardSubTitle>;
|
||||||
|
|
||||||
const handleCardOptionsClick = evt => {
|
const handleCardOptionsClick = evt => {
|
||||||
onQuickActionsClick(evt, { service });
|
onQuickActionsClick(evt, service);
|
||||||
};
|
};
|
||||||
|
|
||||||
const header = isChild
|
const header = isChild
|
||||||
|
@ -2,7 +2,16 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Tooltip, TooltipButton, TooltipDivider } from 'joyent-ui-toolkit';
|
import { Tooltip, TooltipButton, TooltipDivider } from 'joyent-ui-toolkit';
|
||||||
|
|
||||||
const ServicesQuickActions = ({ show, position, service, url, onBlur }) => {
|
const ServicesQuickActions = ({
|
||||||
|
show,
|
||||||
|
position,
|
||||||
|
service,
|
||||||
|
url,
|
||||||
|
onBlur,
|
||||||
|
onRestartClick,
|
||||||
|
onStopClick,
|
||||||
|
onStartClick
|
||||||
|
}) => {
|
||||||
if (!show) {
|
if (!show) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -19,11 +28,25 @@ const ServicesQuickActions = ({ show, position, service, url, onBlur }) => {
|
|||||||
const scaleUrl = `${url}/${service.slug}/scale`;
|
const scaleUrl = `${url}/${service.slug}/scale`;
|
||||||
const deleteUrl = `${url}/${service.slug}/delete`;
|
const deleteUrl = `${url}/${service.slug}/delete`;
|
||||||
|
|
||||||
|
const handleRestartClick = evt => {
|
||||||
|
onRestartClick(evt, service);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStopClick = evt => {
|
||||||
|
onStopClick(evt, service);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStartClick = evt => {
|
||||||
|
onStartClick(evt, service);
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO we'll need to check for service status and diplay start or restart & stop accordingly
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip {...p} onBlur={onBlur}>
|
<Tooltip {...p} onBlur={onBlur}>
|
||||||
<TooltipButton to={scaleUrl}>Scale</TooltipButton>
|
<TooltipButton to={scaleUrl}>Scale</TooltipButton>
|
||||||
<TooltipButton>Restart</TooltipButton>
|
<TooltipButton onClick={handleRestartClick}>Restart</TooltipButton>
|
||||||
<TooltipButton>Stop</TooltipButton>
|
<TooltipButton onClick={handleStopClick}>Stop</TooltipButton>
|
||||||
<TooltipDivider />
|
<TooltipDivider />
|
||||||
<TooltipButton to={deleteUrl}>Delete</TooltipButton>
|
<TooltipButton to={deleteUrl}>Delete</TooltipButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -35,7 +58,10 @@ ServicesQuickActions.propTypes = {
|
|||||||
url: PropTypes.string.isRequired,
|
url: PropTypes.string.isRequired,
|
||||||
position: PropTypes.object,
|
position: PropTypes.object,
|
||||||
show: PropTypes.bool,
|
show: PropTypes.bool,
|
||||||
onBlur: PropTypes.func
|
onBlur: PropTypes.func,
|
||||||
|
onRestartClick: PropTypes.func,
|
||||||
|
onStopClick: PropTypes.func,
|
||||||
|
onStartClick: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ServicesQuickActions;
|
export default ServicesQuickActions;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { compose, graphql, gql } from 'react-apollo';
|
import { compose, graphql, gql } from 'react-apollo';
|
||||||
import ServiceScaleMutation from '@graphql/ServiceScale.gql';
|
import ServicesDeleteMutation from '@graphql/ServicesDeleteMutation.gql';
|
||||||
import { Loader, ErrorMessage } from '@components/messaging';
|
import { Loader, ErrorMessage } from '@components/messaging';
|
||||||
import { ServiceDelete as ServiceDeleteComponent } from '@components/service';
|
import { ServiceDelete as ServiceDeleteComponent } from '@components/service';
|
||||||
import { Modal } from 'joyent-ui-toolkit';
|
import { Modal } from 'joyent-ui-toolkit';
|
||||||
@ -47,16 +47,7 @@ ServiceDelete.propTypes = {
|
|||||||
deleteServices: PropTypes.func.isRequired
|
deleteServices: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const DeleteGql = gql`
|
const DeleteServicesGql = graphql(ServicesDeleteMutation, {
|
||||||
mutation deleteServices($ids: [ID]!) {
|
|
||||||
deleteServices(ids: $ids) {
|
|
||||||
id
|
|
||||||
slug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const DeleteServicesGql = graphql(DeleteGql, {
|
|
||||||
props: ({ mutate }) => ({
|
props: ({ mutate }) => ({
|
||||||
deleteServices: serviceId => mutate({ variables: { ids: [serviceId] } })
|
deleteServices: serviceId => mutate({ variables: { ids: [serviceId] } })
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { compose, graphql } from 'react-apollo';
|
import { compose, graphql } from 'react-apollo';
|
||||||
|
import { reduxForm } from 'redux-form';
|
||||||
import ServiceScaleMutation from '@graphql/ServiceScale.gql';
|
import ServiceScaleMutation from '@graphql/ServiceScale.gql';
|
||||||
import { Loader, ErrorMessage } from '@components/messaging';
|
import { Loader, ErrorMessage } from '@components/messaging';
|
||||||
import { ServiceScale as ServiceScaleComponent } from '@components/service';
|
import { ServiceScale as ServiceScaleComponent } from '@components/service';
|
||||||
@ -20,21 +21,40 @@ class ServiceScale extends Component {
|
|||||||
|
|
||||||
const { service, scale, history, match } = this.props;
|
const { service, scale, history, match } = this.props;
|
||||||
|
|
||||||
|
const validateReplicas = ({ replicas }) => {
|
||||||
|
if (replicas === '') {
|
||||||
|
return {
|
||||||
|
replicas:
|
||||||
|
'Please enter the number of instances you would like to scale to.'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ServiceScaleForm = reduxForm({
|
||||||
|
form: 'scale-service',
|
||||||
|
destroyOnUnmount: true,
|
||||||
|
forceUnregisterOnUnmount: true,
|
||||||
|
validate: validateReplicas,
|
||||||
|
initialValues: {
|
||||||
|
replicas: service.instances.length
|
||||||
|
}
|
||||||
|
})(ServiceScaleComponent);
|
||||||
|
|
||||||
const handleCloseClick = evt => {
|
const handleCloseClick = evt => {
|
||||||
const closeUrl = match.url.split('/').slice(0, -2).join('/');
|
const closeUrl = match.url.split('/').slice(0, -2).join('/');
|
||||||
history.replace(closeUrl);
|
history.replace(closeUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleConfirmClick = evt => {
|
const handleSubmitClick = values => {
|
||||||
scale(service.id, 2);
|
scale(service.id, values.replicas);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal width={460} onCloseClick={handleCloseClick}>
|
<Modal width={460} onCloseClick={handleCloseClick}>
|
||||||
<ServiceScaleComponent
|
<ServiceScaleForm
|
||||||
service={service}
|
service={service}
|
||||||
onConfirmClick={handleConfirmClick}
|
onSubmit={handleSubmitClick.bind(this)}
|
||||||
onCancelClick={handleCloseClick}
|
onCancel={handleCloseClick}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
@ -3,6 +3,9 @@ import { compose, graphql } from 'react-apollo';
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import ServicesQuery from '@graphql/Services.gql';
|
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 { processServices } from '@root/state/selectors';
|
||||||
import { toggleServicesQuickActions } from '@root/state/actions';
|
import { toggleServicesQuickActions } from '@root/state/actions';
|
||||||
@ -34,7 +37,10 @@ class ServiceList extends Component {
|
|||||||
error,
|
error,
|
||||||
servicesQuickActions,
|
servicesQuickActions,
|
||||||
toggleServicesQuickActions,
|
toggleServicesQuickActions,
|
||||||
url
|
url,
|
||||||
|
restartServices,
|
||||||
|
stopServices,
|
||||||
|
startServices
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@ -71,6 +77,18 @@ class ServiceList extends Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRestartClick = (evt, service) => {
|
||||||
|
restartServices(service.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStopClick = (evt, service) => {
|
||||||
|
stopServices(service.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStartClick = (evt, service) => {
|
||||||
|
startServices(service.id);
|
||||||
|
};
|
||||||
|
|
||||||
const handleQuickActionsBlur = o => {
|
const handleQuickActionsBlur = o => {
|
||||||
toggleServicesQuickActions({ show: false });
|
toggleServicesQuickActions({ show: false });
|
||||||
};
|
};
|
||||||
@ -95,6 +113,9 @@ class ServiceList extends Component {
|
|||||||
show={servicesQuickActions.show}
|
show={servicesQuickActions.show}
|
||||||
url={url}
|
url={url}
|
||||||
onBlur={handleQuickActionsBlur}
|
onBlur={handleQuickActionsBlur}
|
||||||
|
onRestartClick={handleRestartClick}
|
||||||
|
onStopClick={handleStopClick}
|
||||||
|
onStartClick={handleStartClick}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
@ -132,6 +153,30 @@ const ServicesGql = graphql(ServicesQuery, {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
const ServiceListWithData = compose(ServicesGql, UiConnect)(ServiceList);
|
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,
|
||||||
|
ServicesStopGql,
|
||||||
|
ServicesStartGql,
|
||||||
|
ServicesGql,
|
||||||
|
UiConnect
|
||||||
|
)(ServiceList);
|
||||||
|
|
||||||
export default ServiceListWithData;
|
export default ServiceListWithData;
|
||||||
|
@ -3,6 +3,9 @@ import { compose, graphql } from 'react-apollo';
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import ServicesQuery from '@graphql/ServicesTopology.gql';
|
import ServicesQuery from '@graphql/ServicesTopology.gql';
|
||||||
|
import ServicesRestartMutation from '@graphql/ServicesRestartMutation.gql';
|
||||||
|
import ServicesStopMutation from '@graphql/ServicesStopMutation.gql';
|
||||||
|
import ServicesStartMutation from '@graphql/ServicesStartMutation.gql';
|
||||||
import unitcalc from 'unitcalc';
|
import unitcalc from 'unitcalc';
|
||||||
|
|
||||||
import { processServices } from '@root/state/selectors';
|
import { processServices } from '@root/state/selectors';
|
||||||
@ -31,7 +34,10 @@ const ServicesTopology = ({
|
|||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
servicesQuickActions,
|
servicesQuickActions,
|
||||||
toggleServicesQuickActions
|
toggleServicesQuickActions,
|
||||||
|
restartServices,
|
||||||
|
stopServices,
|
||||||
|
startServices
|
||||||
}) => {
|
}) => {
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
@ -55,6 +61,18 @@ const ServicesTopology = ({
|
|||||||
toggleServicesQuickActions({ show: false });
|
toggleServicesQuickActions({ show: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRestartClick = (evt, service) => {
|
||||||
|
restartServices(service.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStopClick = (evt, service) => {
|
||||||
|
stopServices(service.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStartClick = (evt, service) => {
|
||||||
|
startServices(service.id);
|
||||||
|
};
|
||||||
|
|
||||||
const handleNodeTitleClick = (evt, { service }) => {
|
const handleNodeTitleClick = (evt, { service }) => {
|
||||||
push(`${url.split('/').slice(0, 3).join('/')}/services/${service.slug}`);
|
push(`${url.split('/').slice(0, 3).join('/')}/services/${service.slug}`);
|
||||||
};
|
};
|
||||||
@ -73,6 +91,9 @@ const ServicesTopology = ({
|
|||||||
position={servicesQuickActions.position}
|
position={servicesQuickActions.position}
|
||||||
url={url}
|
url={url}
|
||||||
onBlur={handleTooltipBlur}
|
onBlur={handleTooltipBlur}
|
||||||
|
onRestartClick={handleRestartClick}
|
||||||
|
onStopClick={handleStopClick}
|
||||||
|
onStartClick={handleStartClick}
|
||||||
/>
|
/>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
</StyledBackground>
|
</StyledBackground>
|
||||||
@ -108,8 +129,30 @@ const ServicesGql = graphql(ServicesQuery, {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
const ServicesTopologyWithData = compose(ServicesGql, UiConnect)(
|
const ServicesRestartGql = graphql(ServicesRestartMutation, {
|
||||||
ServicesTopology
|
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 ServicesTopologyWithData = compose(
|
||||||
|
ServicesRestartGql,
|
||||||
|
ServicesStopGql,
|
||||||
|
ServicesStartGql,
|
||||||
|
ServicesGql,
|
||||||
|
UiConnect
|
||||||
|
)(ServicesTopology);
|
||||||
|
|
||||||
export default ServicesTopologyWithData;
|
export default ServicesTopologyWithData;
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
mutation DeleteServices($ids: [ID]!) {
|
||||||
|
deleteServices(ids: $ids) {
|
||||||
|
id
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
mutation RestartServices($ids: [ID]!) {
|
||||||
|
restartServices(ids: $ids) {
|
||||||
|
id
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
mutation StartServices($ids: [ID]!) {
|
||||||
|
startServices(ids: $ids) {
|
||||||
|
id
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
mutation StopServices($ids: [ID]!) {
|
||||||
|
stopServices(ids: $ids) {
|
||||||
|
id
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
@ -100,10 +100,14 @@ const createServicesFromManifest = ({ deploymentGroupId, raw }) => {
|
|||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteServices = options => getServices({ id: options.ids[0] });
|
const deleteServices = options => {
|
||||||
|
const service = getServices({ id: options.ids[0] });
|
||||||
|
return service;
|
||||||
|
};
|
||||||
|
|
||||||
const scale = options => {
|
const scale = options => {
|
||||||
const service = getServices({ id: options.serviceId })[0];
|
const service = getServices({ id: options.serviceId })[0];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scale: [
|
scale: [
|
||||||
{
|
{
|
||||||
@ -115,6 +119,21 @@ const scale = options => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const restartServices = options => {
|
||||||
|
const service = getServices({ id: options.ids[0] });
|
||||||
|
return service;
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopServices = options => {
|
||||||
|
const service = getServices({ id: options.ids[0] });
|
||||||
|
return service;
|
||||||
|
};
|
||||||
|
|
||||||
|
const startServices = options => {
|
||||||
|
const service = getServices({ id: options.ids[0] });
|
||||||
|
return service;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
portal: getPortal,
|
portal: getPortal,
|
||||||
deploymentGroups: getDeploymentGroups,
|
deploymentGroups: getDeploymentGroups,
|
||||||
@ -131,5 +150,8 @@ module.exports = {
|
|||||||
format: options.format
|
format: options.format
|
||||||
})),
|
})),
|
||||||
deleteServices: (options, request, fn) => fn(null, deleteServices(options)),
|
deleteServices: (options, request, fn) => fn(null, deleteServices(options)),
|
||||||
scale: (options, reguest, fn) => fn(null, scale(options))
|
scale: (options, reguest, fn) => fn(null, scale(options)),
|
||||||
|
restartServices: (options, request, fn) => fn(null, restartServices(options)),
|
||||||
|
stopServices: (options, request, fn) => fn(null, stopServices(options)),
|
||||||
|
startServices: (options, request, fn) => fn(null, startServices(options))
|
||||||
};
|
};
|
||||||
|
@ -191,7 +191,7 @@ type Mutation {
|
|||||||
updateDeploymentGroup(id: ID!, name: String!) : DeploymentGroup
|
updateDeploymentGroup(id: ID!, name: String!) : DeploymentGroup
|
||||||
|
|
||||||
provisionManifest(deploymentGroupId: ID!, type: ManifestType!, format: ManifestFormat!, raw: String!) : Manifest
|
provisionManifest(deploymentGroupId: ID!, type: ManifestType!, format: ManifestFormat!, raw: String!) : Manifest
|
||||||
scale(service: ID!, replicas: Int!) : Version
|
scale(serviceId: ID!, replicas: Int!) : Version
|
||||||
|
|
||||||
stopServices(ids: [ID]!) : [Service]
|
stopServices(ids: [ID]!) : [Service]
|
||||||
startServices(ids: [ID]!) : [Service]
|
startServices(ids: [ID]!) : [Service]
|
||||||
|
@ -9,3 +9,4 @@ export { default as Radio, RadioList } from './radio';
|
|||||||
export { default as Select } from './select';
|
export { default as Select } from './select';
|
||||||
export { default as Toggle, ToggleList } from './toggle';
|
export { default as Toggle, ToggleList } from './toggle';
|
||||||
export { default as NumberInput } from './number-input';
|
export { default as NumberInput } from './number-input';
|
||||||
|
export { NumberInputNormalize } from './number-input';
|
||||||
|
@ -12,7 +12,7 @@ const StyledContainer = styled.div`
|
|||||||
margin-bottom: ${unitcalc(4)};
|
margin-bottom: ${unitcalc(4)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledNumberInput = styled(Baseline(BaseInput(Stylable('input'))))`
|
const StyledNumberInput = styled(BaseInput(Stylable('input')))`
|
||||||
width: ${unitcalc(20)};
|
width: ${unitcalc(20)};
|
||||||
margin: 0 ${unitcalc(1)} 0 0;
|
margin: 0 ${unitcalc(1)} 0 0;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
@ -21,24 +21,41 @@ const StyledNumberInput = styled(Baseline(BaseInput(Stylable('input'))))`
|
|||||||
/**
|
/**
|
||||||
* @example ./usage-number-input.md
|
* @example ./usage-number-input.md
|
||||||
*/
|
*/
|
||||||
const NumberInput = ({ value, ...rest }) => {
|
const NumberInput = BaseInput(props => {
|
||||||
const render = value =>
|
const { children, minValue, maxValue, ...rest } = props;
|
||||||
|
|
||||||
|
const render = value => {
|
||||||
|
const handleMinusClick = evt => {
|
||||||
|
evt.preventDefault();
|
||||||
|
const nextValue = value.input.value - 1;
|
||||||
|
value.input.onChange(nextValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePlusClick = evt => {
|
||||||
|
evt.preventDefault();
|
||||||
|
const nextValue = value.input.value + 1;
|
||||||
|
value.input.onChange(nextValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<StyledNumberInput value={value} />
|
<StyledNumberInput {...props} />
|
||||||
<IconButton onClick={() => {}}>
|
<IconButton onClick={handleMinusClick}>
|
||||||
<MinusIcon verticalAlign="middle" />
|
<MinusIcon verticalAlign="middle" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton onClick={() => {}}>
|
<IconButton onClick={handlePlusClick}>
|
||||||
<PlusIcon verticalAlign="middle" />
|
<PlusIcon verticalAlign="middle" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</StyledContainer>;
|
</StyledContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Subscriber channel="input-group">
|
<Subscriber channel="input-group">
|
||||||
{render}
|
{render}
|
||||||
</Subscriber>
|
</Subscriber>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
NumberInput.propTypes = {
|
NumberInput.propTypes = {
|
||||||
value: PropTypes.number,
|
value: PropTypes.number,
|
||||||
@ -48,3 +65,18 @@ NumberInput.propTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default Baseline(NumberInput);
|
export default Baseline(NumberInput);
|
||||||
|
|
||||||
|
export const NumberInputNormalize = ({ minValue, maxValue }) => {
|
||||||
|
return value => {
|
||||||
|
if (value === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!isNaN(value) &&
|
||||||
|
(isNaN(minValue) || value >= minValue) &&
|
||||||
|
(isNaN(maxValue) || value <= maxValue)
|
||||||
|
) {
|
||||||
|
return Number(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -67,7 +67,8 @@ export {
|
|||||||
Select,
|
Select,
|
||||||
Toggle,
|
Toggle,
|
||||||
ToggleList,
|
ToggleList,
|
||||||
NumberInput
|
NumberInput,
|
||||||
|
NumberInputNormalize
|
||||||
} from './form';
|
} from './form';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
Loading…
Reference in New Issue
Block a user