2018-02-05 17:12:47 +02:00
|
|
|
import React from 'react';
|
2018-02-13 22:03:57 +02:00
|
|
|
import { Margin } from 'styled-components-spacing';
|
|
|
|
import ReduxForm from 'declarative-redux-form';
|
|
|
|
import { destroyAll } from 'react-redux-values';
|
|
|
|
import { destroy, stopSubmit } from 'redux-form';
|
|
|
|
import { connect } from 'react-redux';
|
|
|
|
import { compose, graphql } from 'react-apollo';
|
|
|
|
import intercept from 'apr-intercept';
|
|
|
|
import get from 'lodash.get';
|
|
|
|
import uniqBy from 'lodash.uniqby';
|
|
|
|
import omit from 'lodash.omit';
|
|
|
|
|
|
|
|
import {
|
|
|
|
ViewContainer,
|
|
|
|
H2,
|
|
|
|
Button,
|
|
|
|
StatusLoader,
|
|
|
|
Message,
|
|
|
|
MessageTitle,
|
|
|
|
MessageDescription
|
|
|
|
} from 'joyent-ui-toolkit';
|
|
|
|
|
|
|
|
import CreateImage from '@graphql/create-image.gql';
|
|
|
|
import GetInstance from '@graphql/get-instance.gql';
|
|
|
|
import Details from '@containers/create-image/details';
|
|
|
|
import Tags from '@containers/create-image/tags';
|
|
|
|
import { Forms } from '@root/constants';
|
|
|
|
import parseError from '@state/parse-error';
|
|
|
|
|
|
|
|
const Create = ({
|
|
|
|
step,
|
|
|
|
history,
|
|
|
|
location,
|
|
|
|
match,
|
|
|
|
disabled,
|
|
|
|
loading,
|
|
|
|
loadingError,
|
|
|
|
handleSubmit
|
|
|
|
}) => (
|
|
|
|
<ViewContainer>
|
|
|
|
{loading ? (
|
2018-04-06 17:53:44 +03:00
|
|
|
<Margin top="4">
|
2018-02-13 22:03:57 +02:00
|
|
|
<StatusLoader />
|
|
|
|
</Margin>
|
|
|
|
) : null}
|
|
|
|
{loadingError ? (
|
2018-04-06 17:53:44 +03:00
|
|
|
<Margin top="4">
|
2018-02-13 22:03:57 +02:00
|
|
|
<Message error>
|
|
|
|
<MessageTitle>Ooops!</MessageTitle>
|
|
|
|
<MessageDescription>{loadingError}</MessageDescription>
|
|
|
|
</Message>
|
|
|
|
</Margin>
|
|
|
|
) : null}
|
|
|
|
{!loading && !loadingError ? (
|
2018-04-06 17:53:44 +03:00
|
|
|
<Margin top="4" bottom="5">
|
2018-02-13 22:03:57 +02:00
|
|
|
<H2>Create Image</H2>
|
|
|
|
</Margin>
|
|
|
|
) : null}
|
|
|
|
{!loading && !loadingError ? (
|
|
|
|
<Details
|
|
|
|
history={history}
|
|
|
|
match={match}
|
|
|
|
step="name"
|
|
|
|
expanded={step === 'name'}
|
|
|
|
/>
|
|
|
|
) : null}
|
|
|
|
{!loading && !loadingError ? (
|
|
|
|
<Tags
|
|
|
|
history={history}
|
|
|
|
match={match}
|
|
|
|
step="tag"
|
|
|
|
expanded={step === 'tag'}
|
|
|
|
/>
|
|
|
|
) : null}
|
|
|
|
<ReduxForm form={Forms.CREATE_FORM} onSubmit={handleSubmit}>
|
|
|
|
{({ handleSubmit, submitting }) =>
|
|
|
|
!loading && !loadingError ? (
|
|
|
|
<form onSubmit={handleSubmit}>
|
2018-05-23 19:29:04 +03:00
|
|
|
<Margin top={step === 'tag' ? '7' : '4'}>
|
2018-02-13 22:03:57 +02:00
|
|
|
<Button disabled={disabled} loading={submitting}>
|
|
|
|
Create Image
|
|
|
|
</Button>
|
|
|
|
</Margin>
|
|
|
|
</form>
|
|
|
|
) : null
|
|
|
|
}
|
|
|
|
</ReduxForm>
|
|
|
|
</ViewContainer>
|
|
|
|
);
|
|
|
|
|
|
|
|
export default compose(
|
|
|
|
graphql(CreateImage, { name: 'createImage' }),
|
|
|
|
graphql(GetInstance, {
|
|
|
|
options: ({ match }) => ({
|
2018-02-20 02:35:31 +02:00
|
|
|
ssr: false,
|
2018-02-13 22:03:57 +02:00
|
|
|
variables: {
|
2018-03-21 19:35:51 +02:00
|
|
|
id: get(match, 'params.instance')
|
2018-02-13 22:03:57 +02:00
|
|
|
}
|
|
|
|
}),
|
2018-03-21 19:35:51 +02:00
|
|
|
props: ({ data: { loading, error, machine, variables, ...rest } }) => {
|
2018-02-13 22:03:57 +02:00
|
|
|
const notFoundMsg = `Instance "${variables.name}" not found!`;
|
2018-03-21 19:35:51 +02:00
|
|
|
const notFound = !loading && !machine ? notFoundMsg : false;
|
2018-02-13 22:03:57 +02:00
|
|
|
|
|
|
|
return {
|
2018-03-21 19:35:51 +02:00
|
|
|
instance: machine,
|
2018-02-13 22:03:57 +02:00
|
|
|
loadingError: error ? parseError(error) : notFound,
|
|
|
|
loading
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
connect(({ form, values }, { match }) => {
|
|
|
|
const step = get(match, 'params.step', 'name');
|
|
|
|
|
2018-02-14 21:36:31 +02:00
|
|
|
const name = get(form, `${Forms.FORM_DETAILS}.values.name`, '');
|
|
|
|
const version = get(form, `${Forms.FORM_DETAILS}.values.version`, '');
|
|
|
|
|
|
|
|
const disabled = !(name.length && version.length);
|
2018-02-13 22:03:57 +02:00
|
|
|
|
|
|
|
if (disabled) {
|
|
|
|
return { disabled, step };
|
|
|
|
}
|
|
|
|
|
|
|
|
const description = get(
|
|
|
|
form,
|
|
|
|
`${Forms.FORM_DETAILS}.values.description`,
|
|
|
|
'<instance-description>'
|
|
|
|
);
|
|
|
|
|
|
|
|
const tags = get(values, Forms.CREATE_TAGS, []);
|
|
|
|
|
|
|
|
return {
|
|
|
|
forms: Object.keys(form), // improve this
|
|
|
|
name,
|
|
|
|
description,
|
|
|
|
version,
|
|
|
|
tags,
|
|
|
|
disabled,
|
|
|
|
step
|
|
|
|
};
|
|
|
|
}),
|
|
|
|
connect(null, (dispatch, ownProps) => {
|
|
|
|
const {
|
|
|
|
name,
|
|
|
|
description,
|
|
|
|
version,
|
|
|
|
tags,
|
|
|
|
instance,
|
|
|
|
forms,
|
|
|
|
createImage,
|
|
|
|
history
|
|
|
|
} = ownProps;
|
|
|
|
|
|
|
|
return {
|
|
|
|
handleSubmit: async () => {
|
|
|
|
const _name = name.toLowerCase();
|
|
|
|
const _description = description.toLowerCase();
|
|
|
|
const _version = version.toLowerCase();
|
|
|
|
const _tags = uniqBy(tags, 'name').map(a => omit(a, 'expanded'));
|
|
|
|
|
|
|
|
const [err, res] = await intercept(
|
|
|
|
createImage({
|
|
|
|
variables: {
|
|
|
|
machine: instance.id,
|
|
|
|
name: _name,
|
|
|
|
version: _version,
|
|
|
|
description: _description,
|
|
|
|
tags: _tags
|
|
|
|
}
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
return dispatch(
|
|
|
|
stopSubmit(Forms.CREATE_FORM, {
|
|
|
|
_error: parseError(err)
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatch([destroyAll(), forms.map(name => destroy(name))]);
|
|
|
|
|
|
|
|
const { data } = res;
|
|
|
|
const { createImageFromMachine } = data;
|
2018-02-05 17:12:47 +02:00
|
|
|
|
2018-03-21 19:35:51 +02:00
|
|
|
history.push(`/images/${createImageFromMachine.id}`);
|
2018-02-13 22:03:57 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
})
|
|
|
|
)(Create);
|