feat(instances): add change name

This commit is contained in:
Sara Vieira 2018-03-22 11:22:37 +00:00 committed by Sérgio Ramos
parent 0b9c464bb0
commit 5d274a419a
5 changed files with 9954 additions and 9567 deletions

View File

@ -6,6 +6,7 @@ import { Margin, Padding } from 'styled-components-spacing';
import titleCase from 'title-case'; import titleCase from 'title-case';
import get from 'lodash.get'; import get from 'lodash.get';
import remcalc from 'remcalc'; import remcalc from 'remcalc';
import { Field } from 'redux-form';
import { import {
Card, Card,
@ -21,7 +22,11 @@ import {
DeleteIcon, DeleteIcon,
StartIcon, StartIcon,
StopIcon, StopIcon,
InstanceTypeIcon EditIcon,
InstanceTypeIcon,
Input,
FormMeta,
FormGroup
} from 'joyent-ui-toolkit'; } from 'joyent-ui-toolkit';
import GLOBAL from '@state/global'; import GLOBAL from '@state/global';
@ -58,6 +63,10 @@ const Flex = styled.div`
} }
`; `;
const Actionable = styled(Margin)`
cursor: pointer;
`;
const VerticalDivider = styled.div` const VerticalDivider = styled.div`
width: ${remcalc(1)}; width: ${remcalc(1)};
background: ${props => props.theme.grey}; background: ${props => props.theme.grey};
@ -77,11 +86,49 @@ export const Meta = ({
state, state,
brand, brand,
image, image,
editingName,
handleSubmit,
editName,
disabled,
submitting,
...instance ...instance
}) => [ }) => [
<Row middle="xs"> <Row middle="xs">
<Col xs={12}> <Col xs={12}>
<H2>{instance.name}</H2> <H2>
{editingName ? (
<form onSubmit={handleSubmit}>
<Flex style={{ alignItems: 'start' }}>
<FormGroup name="name" field={Field}>
<Input
onBlur={null}
type="text"
placeholder={instance.name}
disabled={disabled || submitting}
/>
<FormMeta />
</FormGroup>
<Margin left={1}>
<Button
type="submit"
disabled={submitting}
loading={submitting}
inline
>
Add
</Button>
</Margin>
</Flex>
</form>
) : (
<Flex>
{instance.name}
<Actionable left={2} onClick={editName}>
<EditIcon />
</Actionable>
</Flex>
)}
</H2>
</Col> </Col>
</Row>, </Row>,
<Margin top={2} bottom={3}> <Margin top={2} bottom={3}>
@ -131,14 +178,15 @@ export default withTheme(
rebooting = false, rebooting = false,
removing = false, removing = false,
onAction, onAction,
theme = {} theme = {},
...props
}) => ( }) => (
<Row> <Row>
<Col xs={12} sm={12} md={9}> <Col xs={12} sm={12} md={9}>
<Card> <Card>
<CardOutlet> <CardOutlet>
<Padding all={4}> <Padding all={4}>
<Meta {...instance} /> <Meta {...instance} {...props} />
<Row between="xs"> <Row between="xs">
<Col xs={9}> <Col xs={9}>
<Button <Button

View File

@ -2,12 +2,14 @@ import React from 'react';
import { compose, graphql } from 'react-apollo'; import { compose, graphql } from 'react-apollo';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { set } from 'react-redux-values'; import { set } from 'react-redux-values';
import { stopSubmit } from 'redux-form';
import { Margin } from 'styled-components-spacing'; import { Margin } from 'styled-components-spacing';
import intercept from 'apr-intercept'; import intercept from 'apr-intercept';
import isArray from 'lodash.isarray'; import isArray from 'lodash.isarray';
import some from 'lodash.some'; import some from 'lodash.some';
import isInteger from 'lodash.isinteger'; import isInteger from 'lodash.isinteger';
import get from 'lodash.get'; import get from 'lodash.get';
import ReduxForm from 'declarative-redux-form';
import { import {
ViewContainer, ViewContainer,
@ -22,9 +24,13 @@ import StartInstance from '@graphql/start-instance.gql';
import StopInstance from '@graphql/stop-instance.gql'; import StopInstance from '@graphql/stop-instance.gql';
import RebootInstance from '@graphql/reboot-instance.gql'; import RebootInstance from '@graphql/reboot-instance.gql';
import RemoveInstance from '@graphql/remove-instance.gql'; import RemoveInstance from '@graphql/remove-instance.gql';
import RenameMachine from '@graphql/rename-machine.gql';
import SummaryScreen from '@components/instances/summary'; import SummaryScreen from '@components/instances/summary';
import parseError from '@state/parse-error'; import parseError from '@state/parse-error';
import Confirm from '@state/confirm'; import Confirm from '@state/confirm';
import { instanceName as validateName } from '@state/validators';
const FORM = 'change-name';
export const Summary = ({ export const Summary = ({
instance, instance,
@ -35,21 +41,39 @@ export const Summary = ({
starting, starting,
stopping, stopping,
rebooting, rebooting,
removing removing,
editName,
editingName,
handleChangeName,
handleAsyncValidate,
shouldAsyncValidate
}) => { }) => {
const _loading = const _loading =
loading || (!instance && !loadingError) ? <StatusLoader /> : null; loading || (!instance && !loadingError) ? <StatusLoader /> : null;
const _summary = !_loading && const _summary = !_loading &&
instance && ( instance && (
<SummaryScreen <ReduxForm
instance={instance} form={FORM}
starting={starting} onSubmit={handleChangeName}
stopping={stopping} initialValues={{ name: instance.name }}
rebooting={rebooting} asyncValidate={handleAsyncValidate}
removing={removing} shouldAsyncValidate={shouldAsyncValidate}
onAction={handleAction} >
/> {props => (
<SummaryScreen
{...props}
instance={instance}
starting={starting}
stopping={stopping}
rebooting={rebooting}
removing={removing}
onAction={handleAction}
editName={editName}
editingName={editingName}
/>
)}
</ReduxForm>
); );
const _error = loadingError && const _error = loadingError &&
@ -135,6 +159,7 @@ const isPrivate = address => {
export default compose( export default compose(
graphql(StopInstance, { name: 'stop' }), graphql(StopInstance, { name: 'stop' }),
graphql(RenameMachine, { name: 'rename' }),
graphql(StartInstance, { name: 'start' }), graphql(StartInstance, { name: 'start' }),
graphql(RebootInstance, { name: 'reboot' }), graphql(RebootInstance, { name: 'reboot' }),
graphql(RemoveInstance, { name: 'remove' }), graphql(RemoveInstance, { name: 'remove' }),
@ -171,7 +196,7 @@ export default compose(
} }
}), }),
connect( connect(
(state, ownProps) => { ({ values }, ownProps) => {
const { instance = {} } = ownProps; const { instance = {} } = ownProps;
const { id } = instance; const { id } = instance;
@ -181,14 +206,61 @@ export default compose(
return { return {
...ownProps, ...ownProps,
starting: state.values[`${id}-summary-starting`], editingName: get(values, 'editing-name', false),
stopping: state.values[`${id}-summary-stoping`], starting: values[`${id}-summary-starting`],
rebooting: state.values[`${id}-summary-rebooting`], stopping: values[`${id}-summary-stoping`],
removing: state.values[`${id}-summary-removeing`], rebooting: values[`${id}-summary-rebooting`],
mutationError: state.values[`${id}-summary-mutation-error`] removing: values[`${id}-summary-removeing`],
mutationError: values[`${id}-summary-mutation-error`]
}; };
}, },
(disptach, ownProps) => ({ (dispatch, ownProps) => ({
shouldAsyncValidate: ({ trigger }) => {
return trigger === 'change';
},
handleAsyncValidate: validateName,
editName: () =>
dispatch(
set({
name: `editing-name`,
value: true
})
),
handleChangeName: async ({ name, id }) => {
const { instance } = ownProps;
if (name === instance.name) {
return dispatch(
set({
name: `editing-name`,
value: false
})
);
}
const [err] = await intercept(
ownProps.rename({
variables: {
name,
id: get(ownProps, 'match.params.instance')
}
})
);
if (err) {
return dispatch(
stopSubmit(FORM, {
_error: parseError(err)
})
);
}
dispatch(
set({
name: `editing-name`,
value: false
})
);
},
handleAction: async action => { handleAction: async action => {
const { instance } = ownProps; const { instance } = ownProps;
const { id } = instance; const { id } = instance;
@ -201,7 +273,7 @@ export default compose(
const name = `${id}-summary-${gerund}`; const name = `${id}-summary-${gerund}`;
// sets loading to true // sets loading to true
disptach( dispatch(
set({ set({
name, name,
value: true value: true
@ -234,7 +306,7 @@ export default compose(
value: parseError(err) value: parseError(err)
}); });
return disptach([mutationError, setLoadingFalse].filter(Boolean)); return dispatch([mutationError, setLoadingFalse].filter(Boolean));
} }
}) })
) )

View File

@ -0,0 +1,6 @@
mutation renameMachine($id: ID!, $name: String!) {
renameMachine(id: $id, name: $name) {
id
name
}
}