feat(my-joy-beta): initial animations
This commit is contained in:
parent
18701442e1
commit
9d7025cd90
|
@ -46,15 +46,19 @@
|
|||
"punycode": "^2.1.0",
|
||||
"react": "^16.2.0",
|
||||
"react-apollo": "^2.0.4",
|
||||
"react-collapse": "^4.0.3",
|
||||
"react-dom": "^16.2.0",
|
||||
"react-motion": "^0.5.2",
|
||||
"react-redux": "^5.0.6",
|
||||
"react-redux-values": "^1.1.2",
|
||||
"react-router": "^4.2.0",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-transition-group": "^2.2.1",
|
||||
"redux": "^3.7.2",
|
||||
"redux-actions": "^2.2.1",
|
||||
"redux-form": "^7.2.1",
|
||||
"remcalc": "^1.0.10",
|
||||
"scroll-to-element": "^2.0.0",
|
||||
"styled-components": "^3.1.2",
|
||||
"styled-components-spacing": "^2.1.3",
|
||||
"styled-flex-component": "^2.1.0",
|
||||
|
|
|
@ -12,8 +12,9 @@ import { AffinityIcon, Button, H3, Divider } from 'joyent-ui-toolkit';
|
|||
|
||||
import Title from '@components/create-instance/title';
|
||||
import { Rule, Header } from '@components/create-instance/affinity';
|
||||
import Description from '@components/description';
|
||||
import KeyValue from '@components/key-value';
|
||||
import Description from '@components/description';
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
|
||||
const FORM_NAME_CREATE = 'CREATE-INSTANCE-AFFINITY-ADD';
|
||||
const FORM_NAME_EDIT = i => `CREATE-INSTANCE-AFFINITY-EDIT-${i}`;
|
||||
|
@ -43,25 +44,22 @@ export const Affinity = ({
|
|||
handleChangeAddOpen,
|
||||
handleNext,
|
||||
handleEdit,
|
||||
rule
|
||||
rule,
|
||||
step
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title
|
||||
onClick={!expanded && !proceeded && handleEdit}
|
||||
icon={<AffinityIcon />}
|
||||
>
|
||||
<Title id={step} onClick={!expanded && !proceeded && handleEdit} icon={<AffinityIcon />}>
|
||||
Affinity
|
||||
</Title>
|
||||
{expanded ? (
|
||||
<Description>
|
||||
Control placement of instances on the physical servers. Design
|
||||
applications to adapt at failure by distributing application components.
|
||||
Instances are only provisioned when the exact criteria is met.{' '}
|
||||
Control placement of instances on the physical servers. Design applications to adapt at
|
||||
failure by distributing application components. Instances are only provisioned when the
|
||||
exact criteria is met.{' '}
|
||||
<a
|
||||
target="__blank"
|
||||
href="https://docs.joyent.com/public-cloud/instances/docker/how/start-containers#controlling-container-placement"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
rel="noopener noreferrer">
|
||||
Read the docs
|
||||
</a>
|
||||
</Description>
|
||||
|
@ -78,8 +76,7 @@ export const Affinity = ({
|
|||
initialValues={rule}
|
||||
destroyOnUnmount={false}
|
||||
forceUnregisterOnUnmount={true}
|
||||
onSubmit={newValue => handleUpdateAffinityRule(index, newValue)}
|
||||
>
|
||||
onSubmit={newValue => handleUpdateAffinityRule(index, newValue)}>
|
||||
{props => (
|
||||
<KeyValue
|
||||
{...props}
|
||||
|
@ -100,8 +97,7 @@ export const Affinity = ({
|
|||
form={FORM_NAME_CREATE}
|
||||
destroyOnUnmount={false}
|
||||
forceUnregisterOnUnmount={true}
|
||||
onSubmit={handleAddAffinityRules}
|
||||
>
|
||||
onSubmit={handleAddAffinityRules}>
|
||||
{props => (
|
||||
<KeyValue
|
||||
{...props}
|
||||
|
@ -119,11 +115,7 @@ export const Affinity = ({
|
|||
{expanded ? (
|
||||
<Fragment>
|
||||
{affinityRules.length === 0 ? (
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => handleChangeAddOpen(true)}
|
||||
secondary
|
||||
>
|
||||
<Button type="button" onClick={() => handleChangeAddOpen(true)} secondary>
|
||||
Create Affinity Rule
|
||||
</Button>
|
||||
) : null}
|
||||
|
@ -149,6 +141,7 @@ export const Affinity = ({
|
|||
);
|
||||
|
||||
export default compose(
|
||||
AnimatedWrapper,
|
||||
connect(({ values, form }, ownProps) => ({
|
||||
proceeded: get(values, 'create-instance-affinity-proceeded', false),
|
||||
addOpen: get(values, 'create-instance-affinity-add-open', false),
|
||||
|
@ -157,9 +150,7 @@ export default compose(
|
|||
})),
|
||||
connect(null, (dispatch, { affinityRules = [], history }) => ({
|
||||
handleNext: () => {
|
||||
dispatch(
|
||||
set({ name: 'create-instance-affinity-proceeded', value: true })
|
||||
);
|
||||
dispatch(set({ name: 'create-instance-affinity-proceeded', value: true }));
|
||||
|
||||
return history.push(`/instances/~create/summary`);
|
||||
},
|
||||
|
@ -174,16 +165,10 @@ export default compose(
|
|||
|
||||
const appendAffinityRule = set({
|
||||
name: `create-instance-affinity`,
|
||||
value: affinityRules.concat([
|
||||
{ ...RULE_DEFAULTS, ...rule, expanded: false }
|
||||
])
|
||||
value: affinityRules.concat([{ ...RULE_DEFAULTS, ...rule, expanded: false }])
|
||||
});
|
||||
|
||||
return dispatch([
|
||||
destroy(FORM_NAME_CREATE),
|
||||
toggleToClosed,
|
||||
appendAffinityRule
|
||||
]);
|
||||
return dispatch([destroy(FORM_NAME_CREATE), toggleToClosed, appendAffinityRule]);
|
||||
},
|
||||
handleUpdateAffinityRule: (index, newAffinityRule) => {
|
||||
affinityRules[index] = {
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import React, { Component, Fragment } from 'react';
|
||||
import styled, { keyframes } from 'styled-components';
|
||||
import is from 'styled-is';
|
||||
import scrollToElement from 'scroll-to-element';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
const ANIMATION_TIME = 200;
|
||||
|
||||
const Height = keyframes`
|
||||
0% {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
100% {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
`;
|
||||
|
||||
const Animate = styled.div`
|
||||
${is('active')`
|
||||
transform-origin: top;
|
||||
animation: ${Height} ${ANIMATION_TIME}ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
animation-fill-mode: both;
|
||||
`};
|
||||
`;
|
||||
|
||||
const findPos = obj => {
|
||||
let curtop = 0;
|
||||
if (obj.offsetParent) {
|
||||
do {
|
||||
curtop += obj.offsetTop;
|
||||
} while ((obj = obj.offsetParent));
|
||||
return [curtop];
|
||||
}
|
||||
};
|
||||
|
||||
const AnimatedWrapper = WrappedComponent =>
|
||||
class AnimatedWrapper extends Component {
|
||||
render() {
|
||||
return (
|
||||
<Animate active={this.props.match.params.step === this.props.step}>
|
||||
<WrappedComponent {...this.props} />
|
||||
</Animate>
|
||||
);
|
||||
}
|
||||
};
|
||||
export default AnimatedWrapper;
|
|
@ -14,6 +14,7 @@ import Cns, { Footer, AddServiceForm } from '@components/cns';
|
|||
import Tag from '@components/tags';
|
||||
import Title from '@components/create-instance/title';
|
||||
import Description from '@components/description';
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
import GetAccount from '@graphql/get-account.gql';
|
||||
|
||||
const CNS_FORM = 'create-instance-cns';
|
||||
|
@ -30,10 +31,15 @@ const CNSContainer = ({
|
|||
handleEdit,
|
||||
handleToggleCnsEnabled,
|
||||
handleAddService,
|
||||
handleRemoveService
|
||||
handleRemoveService,
|
||||
step
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title onClick={!expanded && !proceeded && handleEdit} icon={<CnsIcon />}>
|
||||
<Title
|
||||
id={step}
|
||||
onClick={!expanded && !proceeded && handleEdit}
|
||||
icon={<CnsIcon />}
|
||||
>
|
||||
Container Name Service
|
||||
</Title>
|
||||
{expanded ? (
|
||||
|
|
|
@ -14,6 +14,7 @@ import { StatusLoader, FirewallIcon, H3, Button } from 'joyent-ui-toolkit';
|
|||
import Title from '@components/create-instance/title';
|
||||
import Description from '@components/description';
|
||||
import FirewallForm from '@components/firewall';
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
import ListFwRules from '@graphql/list-fw-rules.gql';
|
||||
|
||||
const FORM_NAME = 'CREATE-INSTANCE-FIREWALL';
|
||||
|
@ -26,10 +27,12 @@ const Firewall = ({
|
|||
loading = false,
|
||||
enabled = false,
|
||||
handleNext,
|
||||
handleEdit
|
||||
handleEdit,
|
||||
step
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title
|
||||
id={step}
|
||||
onClick={!expanded && !proceeded && handleEdit}
|
||||
icon={<FirewallIcon />}
|
||||
>
|
||||
|
@ -65,8 +68,7 @@ const Firewall = ({
|
|||
tagRules={tagRules}
|
||||
enabled={enabled}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
) : null}
|
||||
</ReduxForm>
|
||||
) : null}
|
||||
{proceeded && !expanded ? (
|
||||
|
@ -94,6 +96,7 @@ const Firewall = ({
|
|||
);
|
||||
|
||||
export default compose(
|
||||
AnimatedWrapper,
|
||||
connect(
|
||||
({ form, values }, ownProps) => ({
|
||||
...ownProps,
|
||||
|
|
|
@ -17,6 +17,7 @@ import { InstanceTypeIcon, StatusLoader, Button } from 'joyent-ui-toolkit';
|
|||
import Description from '@components/description';
|
||||
import Image, { Preview, ImageType } from '@components/create-instance/image';
|
||||
import Title from '@components/create-instance/title';
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
import imageData from '@data/images-map.json';
|
||||
import GetImages from '@graphql/get-images.gql';
|
||||
|
||||
|
@ -29,10 +30,12 @@ const ImageContainer = ({
|
|||
handleSelectLatest,
|
||||
loading,
|
||||
images,
|
||||
vms
|
||||
vms,
|
||||
step
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title
|
||||
id={step}
|
||||
onClick={!expanded && !image.id && handleEdit}
|
||||
icon={<InstanceTypeIcon />}
|
||||
>
|
||||
|
@ -103,6 +106,7 @@ const ImageContainer = ({
|
|||
);
|
||||
|
||||
export default compose(
|
||||
AnimatedWrapper,
|
||||
connect(
|
||||
({ form, values }, ownProps) => {
|
||||
return {
|
||||
|
|
|
@ -36,21 +36,42 @@ const CreateInstance = ({ step, disabled, handleSubmit, history, match }) => (
|
|||
<H2>Create Instances</H2>
|
||||
</Margin>
|
||||
<Margin bottom={4}>
|
||||
<Name history={history} match={match} expanded={step === 'name'} />
|
||||
<Name
|
||||
history={history}
|
||||
match={match}
|
||||
step="name"
|
||||
expanded={step === 'name'}
|
||||
/>
|
||||
</Margin>
|
||||
<Margin bottom={4}>
|
||||
<Image history={history} match={match} expanded={step === 'image'} />
|
||||
<Image
|
||||
history={history}
|
||||
match={match}
|
||||
step="image"
|
||||
expanded={step === 'image'}
|
||||
/>
|
||||
</Margin>
|
||||
<Margin bottom={4}>
|
||||
<Package history={history} match={match} expanded={step === 'package'} />
|
||||
<Package
|
||||
history={history}
|
||||
match={match}
|
||||
step="package"
|
||||
expanded={step === 'package'}
|
||||
/>
|
||||
</Margin>
|
||||
<Margin bottom={4}>
|
||||
<Tags history={history} match={match} expanded={step === 'tags'} />
|
||||
<Tags
|
||||
history={history}
|
||||
match={match}
|
||||
step="tags"
|
||||
expanded={step === 'tags'}
|
||||
/>
|
||||
</Margin>
|
||||
<Margin bottom={4}>
|
||||
<Metadata
|
||||
history={history}
|
||||
match={match}
|
||||
step="metadata"
|
||||
expanded={step === 'metadata'}
|
||||
/>
|
||||
</Margin>
|
||||
|
@ -58,6 +79,7 @@ const CreateInstance = ({ step, disabled, handleSubmit, history, match }) => (
|
|||
<UserScript
|
||||
history={history}
|
||||
match={match}
|
||||
step="user-script"
|
||||
expanded={step === 'user-script'}
|
||||
/>
|
||||
</Margin>
|
||||
|
@ -65,6 +87,7 @@ const CreateInstance = ({ step, disabled, handleSubmit, history, match }) => (
|
|||
<Networks
|
||||
history={history}
|
||||
match={match}
|
||||
step="networks"
|
||||
expanded={step === 'networks'}
|
||||
/>
|
||||
</Margin>
|
||||
|
@ -72,16 +95,23 @@ const CreateInstance = ({ step, disabled, handleSubmit, history, match }) => (
|
|||
<Firewall
|
||||
history={history}
|
||||
match={match}
|
||||
step="firewall"
|
||||
expanded={step === 'firewall'}
|
||||
/>
|
||||
</Margin>
|
||||
<Margin bottom={4}>
|
||||
<CNS history={history} match={match} expanded={step === 'cns'} />
|
||||
<CNS
|
||||
history={history}
|
||||
match={match}
|
||||
step="cns"
|
||||
expanded={step === 'cns'}
|
||||
/>
|
||||
</Margin>
|
||||
<Margin bottom={4}>
|
||||
<Affinity
|
||||
history={history}
|
||||
match={match}
|
||||
step="affinity"
|
||||
expanded={step === 'affinity'}
|
||||
/>
|
||||
</Margin>
|
||||
|
|
|
@ -12,6 +12,7 @@ import { MetadataIcon, Button, H3 } from 'joyent-ui-toolkit';
|
|||
import Title from '@components/create-instance/title';
|
||||
import Description from '@components/description';
|
||||
import KeyValue from '@components/key-value';
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
|
||||
const FORM_NAME_CREATE = 'CREATE-INSTANCE-METADATA-ADD';
|
||||
const FORM_NAME_EDIT = i => `CREATE-INSTANCE-METADATA-EDIT-${i}`;
|
||||
|
@ -28,25 +29,22 @@ export const Metadata = ({
|
|||
handleCancelEdit,
|
||||
handleChangeAddOpen,
|
||||
handleNext,
|
||||
handleEdit
|
||||
handleEdit,
|
||||
id,
|
||||
step
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title
|
||||
onClick={!expanded && !proceeded && handleEdit}
|
||||
icon={<MetadataIcon />}
|
||||
>
|
||||
<Title id={step} onClick={!expanded && !proceeded && handleEdit} icon={<MetadataIcon />}>
|
||||
Metadata
|
||||
</Title>
|
||||
{expanded ? (
|
||||
<Description>
|
||||
Metadata can be used to pass data to the instance. It can also be used
|
||||
to inject a custom boot script. Unlike tags, metadata is only viewable
|
||||
inside the instance.{' '}
|
||||
Metadata can be used to pass data to the instance. It can also be used to inject a custom
|
||||
boot script. Unlike tags, metadata is only viewable inside the instance.{' '}
|
||||
<a
|
||||
target="__blank"
|
||||
href="https://docs.joyent.com/public-cloud/tags-metadata/metadata"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
rel="noopener noreferrer">
|
||||
Read the docs
|
||||
</a>
|
||||
</Description>
|
||||
|
@ -65,8 +63,7 @@ export const Metadata = ({
|
|||
initialValues={{ name, value }}
|
||||
destroyOnUnmount={false}
|
||||
forceUnregisterOnUnmount={true}
|
||||
onSubmit={newValue => handleUpdateMetadata(index, newValue)}
|
||||
>
|
||||
onSubmit={newValue => handleUpdateMetadata(index, newValue)}>
|
||||
{props => (
|
||||
<KeyValue
|
||||
{...props}
|
||||
|
@ -75,9 +72,7 @@ export const Metadata = ({
|
|||
method="edit"
|
||||
input="textarea"
|
||||
type="metadata"
|
||||
onToggleExpanded={() =>
|
||||
expanded ? handleToggleExpanded(index) : null
|
||||
}
|
||||
onToggleExpanded={() => (expanded ? handleToggleExpanded(index) : null)}
|
||||
onCancel={() => handleCancelEdit(index)}
|
||||
onRemove={() => handleRemoveMetadata(index)}
|
||||
/>
|
||||
|
@ -89,8 +84,7 @@ export const Metadata = ({
|
|||
form={FORM_NAME_CREATE}
|
||||
destroyOnUnmount={false}
|
||||
forceUnregisterOnUnmount={true}
|
||||
onSubmit={handleAddMetadata}
|
||||
>
|
||||
onSubmit={handleAddMetadata}>
|
||||
{props => (
|
||||
<KeyValue
|
||||
{...props}
|
||||
|
@ -106,11 +100,7 @@ export const Metadata = ({
|
|||
<div>
|
||||
{expanded ? (
|
||||
<Margin bottom={4}>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => handleChangeAddOpen(true)}
|
||||
secondary
|
||||
>
|
||||
<Button type="button" onClick={() => handleChangeAddOpen(true)} secondary>
|
||||
Add Metadata
|
||||
</Button>
|
||||
<Button type="button" onClick={handleNext}>
|
||||
|
@ -129,6 +119,7 @@ export const Metadata = ({
|
|||
);
|
||||
|
||||
export default compose(
|
||||
AnimatedWrapper,
|
||||
connect(({ values }, ownProps) => ({
|
||||
proceeded: get(values, 'create-instance-metadata-proceeded', false),
|
||||
addOpen: get(values, 'create-instance-metadata-add-open', false),
|
||||
|
@ -136,9 +127,7 @@ export default compose(
|
|||
})),
|
||||
connect(null, (dispatch, { metadata = [], history }) => ({
|
||||
handleNext: () => {
|
||||
dispatch(
|
||||
set({ name: 'create-instance-metadata-proceeded', value: true })
|
||||
);
|
||||
dispatch(set({ name: 'create-instance-metadata-proceeded', value: true }));
|
||||
|
||||
return history.push('/instances/~create/user-script');
|
||||
},
|
||||
|
@ -156,11 +145,7 @@ export default compose(
|
|||
value: metadata.concat([{ ...value, open: false }])
|
||||
});
|
||||
|
||||
return dispatch([
|
||||
destroy(FORM_NAME_CREATE),
|
||||
toggleToClosed,
|
||||
appendMetadata
|
||||
]);
|
||||
return dispatch([destroy(FORM_NAME_CREATE), toggleToClosed, appendMetadata]);
|
||||
},
|
||||
handleUpdateMetadata: (index, newMetadata) => {
|
||||
metadata[index] = {
|
||||
|
|
|
@ -14,6 +14,7 @@ import { NameIcon, H3, Button } from 'joyent-ui-toolkit';
|
|||
import Name from '@components/create-instance/name';
|
||||
import Description from '@components/description';
|
||||
import Title from '@components/create-instance/title';
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
import GetInstance from '@graphql/get-instance-small.gql';
|
||||
import GetRandomName from '@graphql/get-random-name.gql';
|
||||
import { client } from '@state/store';
|
||||
|
@ -30,10 +31,15 @@ const NameContainer = ({
|
|||
shouldAsyncValidate,
|
||||
handleNext,
|
||||
handleRandomize,
|
||||
handleEdit
|
||||
handleEdit,
|
||||
step
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title onClick={!expanded && !name && handleEdit} icon={<NameIcon />}>
|
||||
<Title
|
||||
id={step}
|
||||
onClick={!expanded && !name && handleEdit}
|
||||
icon={<NameIcon />}
|
||||
>
|
||||
Instance name
|
||||
</Title>
|
||||
{expanded ? (
|
||||
|
@ -66,13 +72,13 @@ const NameContainer = ({
|
|||
Edit
|
||||
</Button>
|
||||
</Fragment>
|
||||
) : null
|
||||
}
|
||||
) : null}
|
||||
</ReduxForm>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
export default compose(
|
||||
AnimatedWrapper,
|
||||
graphql(GetRandomName, {
|
||||
fetchPolicy: 'network-only',
|
||||
props: ({ data }) => ({
|
||||
|
|
|
@ -10,9 +10,10 @@ import get from 'lodash.get';
|
|||
|
||||
import { NetworkIcon, Button, H3, StatusLoader } from 'joyent-ui-toolkit';
|
||||
|
||||
import Network from '@components/network';
|
||||
import Description from '@components/description';
|
||||
import Title from '@components/create-instance/title';
|
||||
import Network from '@components/create-instance/network';
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
import ListNetworks from '@graphql/list-networks.gql';
|
||||
|
||||
const FORM_NAME = 'CREATE-INSTANCE-NETWORKS';
|
||||
|
@ -26,26 +27,23 @@ export const Networks = ({
|
|||
setInfoExpanded,
|
||||
setMachinesExpanded,
|
||||
handleNext,
|
||||
handleEdit
|
||||
handleEdit,
|
||||
step
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title
|
||||
onClick={!expanded && !proceeded && handleEdit}
|
||||
icon={<NetworkIcon />}
|
||||
>
|
||||
<Title id={step} onClick={!expanded && !proceeded && handleEdit} icon={<NetworkIcon />}>
|
||||
Networks
|
||||
</Title>
|
||||
{expanded ? (
|
||||
<Description>
|
||||
Instances are automatically connected to a private fabric network, which
|
||||
is the best choice for internal communication within your application.
|
||||
Data center networks are the best choice for exposing your application
|
||||
to the public internet (if the data center network is a public network).{' '}
|
||||
Instances are automatically connected to a private fabric network, which is the best choice
|
||||
for internal communication within your application. Data center networks are the best choice
|
||||
for exposing your application to the public internet (if the data center network is a public
|
||||
network).{' '}
|
||||
<a
|
||||
target="__blank"
|
||||
href="https://docs.joyent.com/public-cloud/network/sdn"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
rel="noopener noreferrer">
|
||||
Read more
|
||||
</a>
|
||||
</Description>
|
||||
|
@ -57,11 +55,7 @@ export const Networks = ({
|
|||
) : null}
|
||||
{loading && expanded ? <StatusLoader /> : null}
|
||||
{!loading ? (
|
||||
<ReduxForm
|
||||
form={FORM_NAME}
|
||||
destroyOnUnmount={false}
|
||||
forceUnregisterOnUnmount={true}
|
||||
>
|
||||
<ReduxForm form={FORM_NAME} destroyOnUnmount={false} forceUnregisterOnUnmount={true}>
|
||||
{props => (
|
||||
<form>
|
||||
{networks.map(
|
||||
|
@ -75,9 +69,7 @@ export const Networks = ({
|
|||
machinesExpanded={machinesExpanded}
|
||||
small={!expanded && selected}
|
||||
onInfoClick={() => setInfoExpanded(id, !infoExpanded)}
|
||||
onMachinesClick={() =>
|
||||
setMachinesExpanded(id, !machinesExpanded)
|
||||
}
|
||||
onMachinesClick={() => setMachinesExpanded(id, !machinesExpanded)}
|
||||
{...network}
|
||||
/>
|
||||
) : null
|
||||
|
@ -88,19 +80,61 @@ export const Networks = ({
|
|||
) : null}
|
||||
<Margin bottom={4}>
|
||||
{expanded ? (
|
||||
<Button type="button" disabled={!selected.length} onClick={handleNext}>
|
||||
Next
|
||||
</Button>
|
||||
) : proceeded ? (
|
||||
<Button type="button" onClick={handleEdit} secondary>
|
||||
Edit
|
||||
</Button>
|
||||
<Description>
|
||||
Instances are automatically connected to a private fabric network, which is the best
|
||||
choice for internal communication within your application. Data center networks are the
|
||||
best choice for exposing your application to the public internet (if the data center
|
||||
network is a public network).{' '}
|
||||
<a target="__blank" href="https://docs.joyent.com/public-cloud/network/sdn">
|
||||
Read more
|
||||
</a>
|
||||
</Description>
|
||||
) : null}
|
||||
{proceeded && !expanded ? (
|
||||
<H3>
|
||||
{selected.length} network{selected.length === 1 ? '' : 's'} added
|
||||
</H3>
|
||||
) : null}
|
||||
{loading && expanded ? <StatusLoader /> : null}
|
||||
{!loading ? (
|
||||
<ReduxForm form={FORM_NAME} destroyOnUnmount={false} forceUnregisterOnUnmount={true}>
|
||||
{props => (
|
||||
<form>
|
||||
{networks.map(
|
||||
({ id, selected, infoExpanded, ...network }) =>
|
||||
!expanded && !selected ? null : (
|
||||
<Network
|
||||
key={id}
|
||||
id={id}
|
||||
selected={selected}
|
||||
infoExpanded={infoExpanded}
|
||||
small={!expanded && selected}
|
||||
onInfoClick={() => setInfoExpanded(id, !infoExpanded)}
|
||||
{...network}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
</ReduxForm>
|
||||
) : null}
|
||||
<Margin bottom={4}>
|
||||
{expanded ? (
|
||||
<Button type="button" disabled={!selected.length} onClick={handleNext}>
|
||||
Next
|
||||
</Button>
|
||||
) : proceeded ? (
|
||||
<Button type="button" onClick={handleEdit} secondary>
|
||||
Edit
|
||||
</Button>
|
||||
) : null}
|
||||
</Margin>
|
||||
</Margin>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
export default compose(
|
||||
AnimatedWrapper,
|
||||
graphql(ListNetworks, {
|
||||
props: ({ data }) => {
|
||||
const { networks = [], loading = false, error = null, refetch } = data;
|
||||
|
@ -122,35 +156,29 @@ export default compose(
|
|||
.map(({ id, name, ...network }) => ({
|
||||
...network,
|
||||
name,
|
||||
selected:
|
||||
empty(id) && name === 'Joyent-SDC-Public'
|
||||
? true
|
||||
: Boolean(selected[id]),
|
||||
infoExpanded: get(
|
||||
values,
|
||||
`create-instance-networks-${id}-info-expanded`,
|
||||
false
|
||||
),
|
||||
machinesExpanded: get(
|
||||
values,
|
||||
`create-instance-networks-${id}-machines-expanded`,
|
||||
false
|
||||
),
|
||||
selected: empty(id) && name === 'Joyent-SDC-Public' ? true : Boolean(selected[id]),
|
||||
infoExpanded: get(values, `create-instance-networks-${id}-info-expanded`, false),
|
||||
machinesExpanded: get(values, `create-instance-networks-${id}-machines-expanded`, false),
|
||||
id
|
||||
}))
|
||||
.sort((a, b) => a.name < b.name);
|
||||
|
||||
return {
|
||||
proceeded: get(values, 'create-instance-networks-proceeded', false),
|
||||
selected: _networks.filter(({ selected }) => selected),
|
||||
networks: _networks
|
||||
networks: networks
|
||||
.map(({ id, name, ...network }) => ({
|
||||
...network,
|
||||
name,
|
||||
selected: empty(id) && name === 'Joyent-SDC-Public' ? true : Boolean(selected[id]),
|
||||
infoExpanded: get(values, `create-instance-networks-${id}-expanded`, false),
|
||||
id
|
||||
}))
|
||||
.sort((a, b) => a.name < b.name)
|
||||
};
|
||||
},
|
||||
(dispatch, { history }) => ({
|
||||
handleNext: () => {
|
||||
dispatch(
|
||||
set({ name: 'create-instance-networks-proceeded', value: true })
|
||||
);
|
||||
dispatch(set({ name: 'create-instance-networks-proceeded', value: true }));
|
||||
|
||||
return history.push('/instances/~create/firewall');
|
||||
},
|
||||
|
|
|
@ -13,7 +13,6 @@ import constantCase from 'constant-case';
|
|||
import { reset } from 'redux-form';
|
||||
|
||||
import { PackageIcon, StatusLoader } from 'joyent-ui-toolkit';
|
||||
|
||||
import {
|
||||
Filters,
|
||||
Packages,
|
||||
|
@ -21,6 +20,7 @@ import {
|
|||
Overview
|
||||
} from '@components/create-instance/package';
|
||||
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
import Title from '@components/create-instance/title';
|
||||
import Description from '@components/description';
|
||||
import getPackages from '@graphql/get-packages.gql';
|
||||
|
@ -40,10 +40,12 @@ const PackageContainer = ({
|
|||
sortOrder,
|
||||
handleSortBy,
|
||||
sortBy,
|
||||
resetFilters
|
||||
resetFilters,
|
||||
step
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title
|
||||
id={step}
|
||||
onClick={!expanded && !selected.id && handleEdit}
|
||||
icon={<PackageIcon />}
|
||||
>
|
||||
|
@ -117,6 +119,7 @@ const PackageContainer = ({
|
|||
);
|
||||
|
||||
export default compose(
|
||||
AnimatedWrapper,
|
||||
graphql(getPackages, {
|
||||
props: ({ data: { loading, packages = [] } }) => ({
|
||||
loading,
|
||||
|
|
|
@ -10,9 +10,10 @@ import get from 'lodash.get';
|
|||
import { TagsIcon, Button, H3, TagList } from 'joyent-ui-toolkit';
|
||||
|
||||
import Title from '@components/create-instance/title';
|
||||
import Tag from '@components/tags';
|
||||
import KeyValue from '@components/key-value';
|
||||
import Description from '@components/description';
|
||||
import Tag from '@components/tags';
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
|
||||
const FORM_NAME_CREATE = 'CREATE-INSTANCE-TAGS-ADD';
|
||||
const FORM_NAME_EDIT = i => `CREATE-INSTANCE-TAGS-EDIT-${i}`;
|
||||
|
@ -29,10 +30,15 @@ export const Tags = ({
|
|||
handleCancelEdit,
|
||||
handleChangeAddOpen,
|
||||
handleNext,
|
||||
step,
|
||||
handleEdit
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title onClick={!expanded && !proceeded && handleEdit} icon={<TagsIcon />}>
|
||||
<Title
|
||||
id={step}
|
||||
onClick={!expanded && !proceeded && handleEdit}
|
||||
icon={<TagsIcon />}
|
||||
>
|
||||
Tags
|
||||
</Title>
|
||||
{expanded ? (
|
||||
|
@ -114,6 +120,7 @@ export const Tags = ({
|
|||
);
|
||||
|
||||
export default compose(
|
||||
AnimatedWrapper,
|
||||
connect(({ values }, ownProps) => ({
|
||||
proceeded: get(values, 'create-instance-tags-proceeded', false),
|
||||
addOpen: get(values, 'create-instance-tags-add-open', false),
|
||||
|
|
|
@ -12,6 +12,7 @@ import { ScriptIcon, Button } from 'joyent-ui-toolkit';
|
|||
import KeyValue from '@components/key-value';
|
||||
import Description from '@components/description';
|
||||
import Title from '@components/create-instance/title';
|
||||
import AnimatedWrapper from '@containers/create-instance/animatedWrapper';
|
||||
|
||||
const FORM_NAME = 'create-instance-user-script';
|
||||
|
||||
|
@ -26,10 +27,11 @@ export const UserScript = ({
|
|||
handleSubmit,
|
||||
handleRemove,
|
||||
handleNext,
|
||||
handleEdit
|
||||
handleEdit,
|
||||
step
|
||||
}) => (
|
||||
<Fragment>
|
||||
<Title onClick={!proceeded && handleEdit} icon={<ScriptIcon />}>
|
||||
<Title id={step} onClick={!proceeded && handleEdit} icon={<ScriptIcon />}>
|
||||
User Script
|
||||
</Title>
|
||||
{expanded ? (
|
||||
|
@ -57,8 +59,7 @@ export const UserScript = ({
|
|||
onRemove={handleRemove}
|
||||
onlyValue
|
||||
/>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</ReduxForm>
|
||||
<div>
|
||||
{expanded ? (
|
||||
|
@ -90,6 +91,7 @@ export const UserScript = ({
|
|||
);
|
||||
|
||||
export default compose(
|
||||
AnimatedWrapper,
|
||||
connect(
|
||||
({ values }, ownProps) => {
|
||||
const script = get(values, 'create-instance-user-script', {
|
||||
|
|
83
yarn.lock
83
yarn.lock
|
@ -2195,6 +2195,10 @@ center-align@^0.1.1:
|
|||
align-text "^0.1.3"
|
||||
lazy-cache "^1.0.3"
|
||||
|
||||
chain-function@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
|
||||
|
||||
chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
|
@ -2565,10 +2569,41 @@ compare-func@^1.3.1:
|
|||
array-ify "^1.0.0"
|
||||
dot-prop "^3.0.0"
|
||||
|
||||
component-clone@0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/component-clone/-/component-clone-0.2.2.tgz#c7f5979822880fad8cfb0962ba29186d061ee04f"
|
||||
dependencies:
|
||||
component-type "*"
|
||||
|
||||
component-emitter@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.0.tgz#ccd113a86388d06482d03de3fc7df98526ba8efe"
|
||||
|
||||
component-emitter@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
|
||||
|
||||
component-raf@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/component-raf/-/component-raf-1.2.0.tgz#b2bc72d43f1b014fde7a4b3c447c764bc73ccbaa"
|
||||
|
||||
component-tween@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/component-tween/-/component-tween-1.2.0.tgz#cc39ce5dbab05b52825f41d1947638a0b01b2b8a"
|
||||
dependencies:
|
||||
component-clone "0.2.2"
|
||||
component-emitter "1.2.0"
|
||||
component-type "1.1.0"
|
||||
ease-component "1.0.0"
|
||||
|
||||
component-type@*:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9"
|
||||
|
||||
component-type@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.1.0.tgz#95b666aad53e5c8d1f2be135c45b5d499197c0c5"
|
||||
|
||||
compressible@~2.0.11:
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66"
|
||||
|
@ -3422,6 +3457,10 @@ dom-converter@~0.1:
|
|||
dependencies:
|
||||
utila "~0.3"
|
||||
|
||||
dom-helpers@^3.2.0:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
|
||||
|
||||
dom-serializer@0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
|
||||
|
@ -3518,6 +3557,10 @@ duplicate-package-checker-webpack-plugin@^2.1.0:
|
|||
lodash "^4.17.4"
|
||||
semver "^5.4.1"
|
||||
|
||||
ease-component@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ease-component/-/ease-component-1.0.0.tgz#b375726db0b5b04595b77440396fec7daa5d77c9"
|
||||
|
||||
ecc-jsbn@~0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
|
||||
|
@ -8507,7 +8550,7 @@ quotation@^1.0.0, quotation@^1.0.1, quotation@^1.1.0:
|
|||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/quotation/-/quotation-1.1.0.tgz#3f9c9b2e7780856f27c5015bec628d690e82c70d"
|
||||
|
||||
raf@3.4.0:
|
||||
raf@3.4.0, raf@^3.1.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"
|
||||
dependencies:
|
||||
|
@ -8600,6 +8643,12 @@ react-codemirror2@^3.0.3, react-codemirror2@^3.0.7:
|
|||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-3.0.7.tgz#d5d9888158263ae56da766539d7803486566ab9f"
|
||||
|
||||
react-collapse@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/react-collapse/-/react-collapse-4.0.3.tgz#b96de959ed0092a43534630b599a4753dd76d543"
|
||||
dependencies:
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-create-component-from-tag-prop@^1.2.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-create-component-from-tag-prop/-/react-create-component-from-tag-prop-1.3.1.tgz#5389407d99f88ba2b36351780a6094470b44a7c7"
|
||||
|
@ -8712,6 +8761,14 @@ react-icons@^2.2.7:
|
|||
dependencies:
|
||||
react-icon-base "2.1.0"
|
||||
|
||||
react-motion@^0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316"
|
||||
dependencies:
|
||||
performance-now "^0.2.0"
|
||||
prop-types "^15.5.8"
|
||||
raf "^3.1.0"
|
||||
|
||||
react-popper@^0.7.5:
|
||||
version "0.7.5"
|
||||
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.7.5.tgz#71c25946f291db381231281f6b95729e8b801596"
|
||||
|
@ -8894,6 +8951,17 @@ react-test-renderer@^16.2.0:
|
|||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
react-transition-group@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10"
|
||||
dependencies:
|
||||
chain-function "^1.0.0"
|
||||
classnames "^2.2.5"
|
||||
dom-helpers "^3.2.0"
|
||||
loose-envify "^1.3.1"
|
||||
prop-types "^15.5.8"
|
||||
warning "^3.0.0"
|
||||
|
||||
react@16.2.0, react@^0.14.0, react@^15.5.4, react@^16.2.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba"
|
||||
|
@ -9694,6 +9762,19 @@ schema-utils@^0.4.2:
|
|||
ajv "^5.0.0"
|
||||
ajv-keywords "^2.1.0"
|
||||
|
||||
scroll-to-element@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/scroll-to-element/-/scroll-to-element-2.0.0.tgz#3467330e3384743b7295ac64b30279990c5ac164"
|
||||
dependencies:
|
||||
scroll-to "0.0.2"
|
||||
|
||||
scroll-to@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/scroll-to/-/scroll-to-0.0.2.tgz#936d398a9133660a2492145c2c0081dfcb0728f3"
|
||||
dependencies:
|
||||
component-raf "1.2.0"
|
||||
component-tween "1.2.0"
|
||||
|
||||
select-hose@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
|
|
Loading…
Reference in New Issue