feat: create instance from image, and vice-versa

This commit is contained in:
Sérgio Ramos 2018-02-15 14:37:59 +00:00 committed by Sérgio Ramos
parent bf9a85e4fd
commit d879202b4e
77 changed files with 5915 additions and 4510 deletions

View File

@ -30,12 +30,20 @@ const Link = styled.a`
export default () => (
<List>
<ListItem>
<Link href="https://www.joyent.com/about/policies" target="_blank">
<Link
href="https://www.joyent.com/about/policies"
target="__blank"
rel="noopener noreferrer"
>
Policies
</Link>
</ListItem>
<ListItem>
<Link href="https://www.joyent.com/networking-and-security/security-compliance">
<Link
href="https://www.joyent.com/networking-and-security/security-compliance"
target="__blank"
rel="noopener noreferrer"
>
Compliance
</Link>
</ListItem>

View File

@ -36,6 +36,12 @@ const CardAnchor = styled(Anchor)`
text-decoration: none;
`;
const ItemAnchor = styled(Anchor)`
color: ${props => props.theme.text};
-webkit-text-fill-color: currentcolor;
text-decoration: none;
`;
const Type = styled(Margin)`
overflow: hidden;
white-space: nowrap;
@ -62,7 +68,15 @@ const Actions = styled(Flex)`
min-width: 48px;
`;
export const Image = ({ name, os, version, type, removing, onRemove }) => (
export const Image = ({
name,
os,
version,
type,
removing,
onRemove,
onCreateInstance
}) => (
<Margin bottom={3}>
<CardAnchor to={`/${name}`} component={Link}>
<Card radius>
@ -108,14 +122,14 @@ export const Image = ({ name, os, version, type, removing, onRemove }) => (
<ActionsIcon />
</PopoverTarget>
<Popover placement="bottom">
<PopoverItem disabled={false}>
<Anchor
noUnderline
black
href={`instances/~create/?image=${name}`}
<PopoverItem disabled={false} onClick={onCreateInstance}>
<ItemAnchor
href={`http://localhost:3069/~create/?image=${name}`}
target="__blank"
rel="noopener noreferrer"
>
Create Instance
</Anchor>
</ItemAnchor>
</PopoverItem>
<PopoverDivider />
<PopoverItem disabled={removing} onClick={onRemove}>

View File

@ -115,7 +115,9 @@ export default withTheme(({ theme = {}, onRemove, removing, ...image }) => (
<Medium>
<Button
type="button"
href={`instances/~create/?image=${image.name}`}
href={`http://localhost:3069/~create/?image=${image.name}`}
target="__blank"
rel="noopener noreferrer"
bold
icon
>

View File

@ -37,6 +37,7 @@ export const List = ({
error = null,
history,
typeValue,
handleCreateInstance,
handleRemove
}) => (
<ViewContainer main>
@ -78,7 +79,11 @@ export const List = ({
<Row>
{images.map(image => (
<Col sm={4}>
<Image {...image} onRemove={() => handleRemove(image.id)} />
<Image
{...image}
onCreateInstance={() => handleCreateInstance(image)}
onRemove={() => handleRemove(image.id)}
/>
</Col>
))}
{!images.length && !loading ? (
@ -152,6 +157,10 @@ export default compose(
};
},
(dispatch, { removeImage, history }) => ({
handleCreateInstance: image =>
window
.open(`http://localhost:3069/~create/?image=${image.name}`, '_blank')
.focus(),
handleRemove: async id => {
dispatch([set({ name: `remove-mutation-${id}-loading`, value: true })]);

View File

@ -155,7 +155,7 @@ export default compose(
handleRemoveTag: async name => {
dispatch(set({ name: `${image.id}-mutating`, value: true }));
const [err, res] = await intercept(
const [err] = await intercept(
updateTags({
variables: {
id: image.id,
@ -180,7 +180,7 @@ export default compose(
handleAddTag: async ({ name, value }) => {
dispatch(set({ name: `${image.id}-mutating`, value: true }));
const [err, res] = await intercept(
const [err] = await intercept(
updateTags({
variables: {
id: image.id,

View File

@ -25,9 +25,9 @@
"constant-case": "^2.0.0",
"date-fns": "^1.29.0",
"declarative-redux-form": "^2.0.8",
"joyent-logo-assets": "^1.0.0",
"execa": "^0.9.0",
"inert": "^5.1.0",
"joyent-logo-assets": "^1.0.0",
"joyent-manifest-editor": "^1.4.0",
"joyent-react-scripts": "^7.3.0",
"joyent-react-styled-flexboxgrid": "^2.2.3",
@ -51,6 +51,7 @@
"param-case": "^2.1.1",
"prop-types": "^15.6.0",
"punycode": "^2.1.0",
"query-string": "^5.1.0",
"react": "^16.2.0",
"react-apollo": "^2.0.4",
"react-dom": "^16.2.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -82,7 +82,8 @@ exports[`renders <AddServiceForm /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c9 + button {
.c9 + button,
.c9 + a {
margin-left: 0.375rem;
}
@ -90,6 +91,11 @@ exports[`renders <AddServiceForm /> without throwing 1`] = `
display: inline-block;
}
.c8 + button,
.c8 + a {
margin-left: 0.375rem;
}
.c7 {
box-sizing: border-box;
display: inline-block;
@ -417,7 +423,8 @@ exports[`renders <AddServiceForm pristine /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c9 + button {
.c9 + button,
.c9 + a {
margin-left: 0.375rem;
}
@ -425,6 +432,11 @@ exports[`renders <AddServiceForm pristine /> without throwing 1`] = `
display: inline-block;
}
.c8 + button,
.c8 + a {
margin-left: 0.375rem;
}
.c7 {
box-sizing: border-box;
display: inline-block;

View File

@ -30,7 +30,8 @@ exports[`renders <KeyValue /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -38,6 +39,11 @@ exports[`renders <KeyValue /> without throwing 1`] = `
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -1299,7 +1305,8 @@ exports[`renders <KeyValue input="input" /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -1307,6 +1314,11 @@ exports[`renders <KeyValue input="input" /> without throwing 1`] = `
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -2329,7 +2341,8 @@ exports[`renders <KeyValue input="textarea" /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c24 + button {
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
@ -2350,6 +2363,11 @@ exports[`renders <KeyValue input="textarea" /> without throwing 1`] = `
display: inline-block;
}
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
.c22 {
box-sizing: border-box;
display: inline-block;
@ -3417,7 +3435,8 @@ exports[`renders <KeyValue method="add" /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -3425,6 +3444,11 @@ exports[`renders <KeyValue method="add" /> without throwing 1`] = `
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -4447,7 +4471,8 @@ exports[`renders <KeyValue method="edit" /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -4455,6 +4480,11 @@ exports[`renders <KeyValue method="edit" /> without throwing 1`] = `
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -5488,7 +5518,8 @@ exports[`renders <KeyValue removing /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -5549,6 +5580,11 @@ exports[`renders <KeyValue removing /> without throwing 1`] = `
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -6602,7 +6638,8 @@ exports[`renders <KeyValue submitting /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -6663,6 +6700,11 @@ exports[`renders <KeyValue submitting /> without throwing 1`] = `
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c24 {
box-sizing: border-box;
display: inline-block;
@ -7771,7 +7813,8 @@ exports[`renders <KeyValue type="tag" /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -7779,6 +7822,11 @@ exports[`renders <KeyValue type="tag" /> without throwing 1`] = `
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;

View File

@ -47,7 +47,8 @@ exports[`renders <AddForm /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -55,6 +56,11 @@ exports[`renders <AddForm /> without throwing 1`] = `
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -1077,7 +1083,8 @@ exports[`renders <EditForm /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -1085,6 +1092,11 @@ exports[`renders <EditForm /> without throwing 1`] = `
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -324,8 +324,10 @@ exports[`renders <Images images=[{name: stuff, imageName: stuff}] /> without thr
onClick={[Function]}
>
<svg
height="42"
id="image-img-stuff"
viewBox="0 0 42 42"
width="42"
xmlns="http://www.w3.org/2000/svg"
>
<title>

View File

@ -99,7 +99,8 @@ exports[`renders <Name /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c13 + button {
.c13 + button,
.c13 + a {
margin-left: 0.375rem;
}
@ -107,6 +108,11 @@ exports[`renders <Name /> without throwing 1`] = `
display: inline-block;
}
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
.c11 {
box-sizing: border-box;
display: inline-block;
@ -529,7 +535,8 @@ exports[`renders <Name expanded /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c13 + button {
.c13 + button,
.c13 + a {
margin-left: 0.375rem;
}
@ -537,6 +544,11 @@ exports[`renders <Name expanded /> without throwing 1`] = `
display: inline-block;
}
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
.c11 {
box-sizing: border-box;
display: inline-block;
@ -959,7 +971,8 @@ exports[`renders <Name name="test" /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c13 + button {
.c13 + button,
.c13 + a {
margin-left: 0.375rem;
}
@ -967,6 +980,11 @@ exports[`renders <Name name="test" /> without throwing 1`] = `
display: inline-block;
}
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
.c11 {
box-sizing: border-box;
display: inline-block;
@ -1389,7 +1407,8 @@ exports[`renders <Name pristine={false} /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c13 + button {
.c13 + button,
.c13 + a {
margin-left: 0.375rem;
}
@ -1397,6 +1416,11 @@ exports[`renders <Name pristine={false} /> without throwing 1`] = `
display: inline-block;
}
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
.c11 {
box-sizing: border-box;
display: inline-block;

View File

@ -105,7 +105,8 @@ exports[`renders <Filters /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c16 + button {
.c16 + button,
.c16 + a {
margin-left: 0.375rem;
}
@ -176,6 +177,11 @@ exports[`renders <Filters /> without throwing 1`] = `
display: inline-block;
}
.c15 + button,
.c15 + a {
margin-left: 0.375rem;
}
.c14 {
box-sizing: border-box;
display: inline-block;

View File

@ -59,7 +59,7 @@ const Image = ({ onClick, active, ...image }) => {
<Col md={2} sm={3}>
<Margin bottom={3}>
<Card id={ids[0]} onClick={handleClick} active={active} preview>
<Logo id={ids[1]} />
<Logo id={ids[1]} width="42" height="42" />
<H4>{titleCase(imageName)}</H4>
<FormGroup name="image" field={Field}>
<Version onBlur={null}>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -3611,7 +3611,7 @@ exports[`renders <Item /> without throwing 1`] = `
>
<a
className="c11 c12 c13"
to="/instances/undefined"
to="/undefined"
/>
</td>
<td
@ -4090,7 +4090,7 @@ exports[`renders <Item {...item} /> without throwing 1`] = `
>
<a
className="c11 c12 c13"
to="/instances/name"
to="/name"
>
name
</a>
@ -4571,7 +4571,7 @@ exports[`renders <Item allowedActions /> without throwing 1`] = `
>
<a
className="c11 c12 c13"
to="/instances/undefined"
to="/undefined"
/>
</td>
<td
@ -5078,7 +5078,7 @@ exports[`renders <Item mutating /> without throwing 1`] = `
>
<a
className="c11 c12 c13"
to="/instances/undefined"
to="/undefined"
/>
</td>
<td

View File

@ -30,7 +30,8 @@ exports[`renders <AddForm /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c24 + button {
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
@ -51,6 +52,11 @@ exports[`renders <AddForm /> without throwing 1`] = `
display: inline-block;
}
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
.c22 {
box-sizing: border-box;
display: inline-block;
@ -1118,7 +1124,8 @@ exports[`renders <EditForm /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c25 + button {
.c25 + button,
.c25 + a {
margin-left: 0.375rem;
}
@ -1139,6 +1146,11 @@ exports[`renders <EditForm /> without throwing 1`] = `
display: inline-block;
}
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
.c23 {
box-sizing: border-box;
display: inline-block;

View File

@ -58,7 +58,8 @@ exports[`renders <Toolbar /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c10 + button {
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
@ -66,6 +67,11 @@ exports[`renders <Toolbar /> without throwing 1`] = `
display: inline-block;
}
.c9 + button,
.c9 + a {
margin-left: 0.375rem;
}
.c8 {
box-sizing: border-box;
display: inline-block;
@ -394,7 +400,8 @@ exports[`renders <Toolbar actionLabel /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c10 + button {
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
@ -402,6 +409,11 @@ exports[`renders <Toolbar actionLabel /> without throwing 1`] = `
display: inline-block;
}
.c9 + button,
.c9 + a {
margin-left: 0.375rem;
}
.c8 {
box-sizing: border-box;
display: inline-block;
@ -730,7 +742,8 @@ exports[`renders <Toolbar actionable /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c10 + button {
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
@ -738,6 +751,11 @@ exports[`renders <Toolbar actionable /> without throwing 1`] = `
display: inline-block;
}
.c9 + button,
.c9 + a {
margin-left: 0.375rem;
}
.c8 {
box-sizing: border-box;
display: inline-block;
@ -1088,7 +1106,8 @@ exports[`renders <Toolbar onActionClick /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c10 + button {
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
@ -1096,6 +1115,11 @@ exports[`renders <Toolbar onActionClick /> without throwing 1`] = `
display: inline-block;
}
.c9 + button,
.c9 + a {
margin-left: 0.375rem;
}
.c8 {
box-sizing: border-box;
display: inline-block;
@ -1424,7 +1448,8 @@ exports[`renders <Toolbar searchLabel /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c10 + button {
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
@ -1432,6 +1457,11 @@ exports[`renders <Toolbar searchLabel /> without throwing 1`] = `
display: inline-block;
}
.c9 + button,
.c9 + a {
margin-left: 0.375rem;
}
.c8 {
box-sizing: border-box;
display: inline-block;
@ -1760,7 +1790,8 @@ exports[`renders <Toolbar searchPlaceholder /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c10 + button {
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
@ -1768,6 +1799,11 @@ exports[`renders <Toolbar searchPlaceholder /> without throwing 1`] = `
display: inline-block;
}
.c9 + button,
.c9 + a {
margin-left: 0.375rem;
}
.c8 {
box-sizing: border-box;
display: inline-block;
@ -2096,7 +2132,8 @@ exports[`renders <Toolbar searchable /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c10 + button {
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
@ -2104,6 +2141,11 @@ exports[`renders <Toolbar searchable /> without throwing 1`] = `
display: inline-block;
}
.c9 + button,
.c9 + a {
margin-left: 0.375rem;
}
.c8 {
box-sizing: border-box;
display: inline-block;

View File

@ -41,6 +41,12 @@ const A = styled(Anchor)`
font-weight: ${props => props.theme.font.weight.semibold};
`;
const ItemAnchor = styled(Anchor)`
color: ${props => props.theme.text};
-webkit-text-fill-color: currentcolor;
text-decoration: none;
`;
export const Item = ({
id = '',
name,
@ -48,6 +54,7 @@ export const Item = ({
created,
allowedActions = {},
mutating = false,
onCreateImage,
onStart,
onStop,
onReboot,
@ -60,7 +67,7 @@ export const Item = ({
</FormGroup>
</TableTd>
<TableTd middle left>
<A to={`/instances/${name}`} component={Link}>
<A to={`/${name}`} component={Link}>
{name}
</A>
</TableTd>
@ -97,6 +104,16 @@ export const Item = ({
Reboot
</PopoverItem>
<PopoverDivider />
<PopoverItem disabled={false} onClick={onCreateImage}>
<ItemAnchor
href={`http://localhost:3070/~create/${name}`}
target="__blank"
rel="noopener noreferrer"
>
Create Image
</ItemAnchor>
</PopoverItem>
<PopoverDivider />
<PopoverItem disabled={!allowedActions.remove} onClick={onRemove}>
Remove
</PopoverItem>

View File

@ -14,12 +14,13 @@ import {
Button,
H2,
Label,
CopiableField,
QueryBreakpoints,
DotIcon,
DeleteIcon,
StartIcon,
StopIcon,
CopiableField
InstanceTypeIcon
} from 'joyent-ui-toolkit';
const { SmallOnly, Medium } = QueryBreakpoints;
@ -129,6 +130,16 @@ export default withTheme(
<Meta {...instance} />
<Row between="xs">
<Col xs={9}>
<Button
href={`http://localhost:3070/~create/${instance.name}`}
target="__blank"
rel="noopener noreferrer"
secondary
small
icon
>
<InstanceTypeIcon />
</Button>
<SmallOnly>
<Button
type="button"

View File

@ -43,7 +43,8 @@ exports[`renders <Footer/> without throwing 1`] = `
<a
className="c2"
href="https://www.joyent.com/about/policies"
target="_blank"
rel="noopener noreferrer"
target="__blank"
>
Policies
</a>
@ -54,6 +55,8 @@ exports[`renders <Footer/> without throwing 1`] = `
<a
className="c2"
href="https://www.joyent.com/networking-and-security/security-compliance"
rel="noopener noreferrer"
target="__blank"
>
Compliance
</a>

View File

@ -96,7 +96,7 @@ exports[`renders <Menu links /> without throwing 1`] = `
>
<a
className="c4 c5 c6"
to="/instances/:name/summary"
to="/:name/summary"
>
summary
</a>
@ -106,7 +106,7 @@ exports[`renders <Menu links /> without throwing 1`] = `
>
<a
className="c4 c5 c6"
to="/instances/:name/tags"
to="/:name/tags"
>
tags
</a>
@ -116,7 +116,7 @@ exports[`renders <Menu links /> without throwing 1`] = `
>
<a
className="c4 c5 c6"
to="/instances/:name/metadata"
to="/:name/metadata"
>
metadata
</a>
@ -126,7 +126,7 @@ exports[`renders <Menu links /> without throwing 1`] = `
>
<a
className="c4 c5 c6"
to="/instances/:name/networks"
to="/:name/networks"
>
networks
</a>
@ -136,7 +136,7 @@ exports[`renders <Menu links /> without throwing 1`] = `
>
<a
className="c4 c5 c6"
to="/instances/:name/firewall"
to="/:name/firewall"
>
firewall
</a>
@ -146,7 +146,7 @@ exports[`renders <Menu links /> without throwing 1`] = `
>
<a
className="c4 c5 c6"
to="/instances/:name/dns"
to="/:name/dns"
>
dns
</a>
@ -156,7 +156,7 @@ exports[`renders <Menu links /> without throwing 1`] = `
>
<a
className="c4 c5 c6"
to="/instances/:name/snapshots"
to="/:name/snapshots"
>
snapshots
</a>

View File

@ -21,31 +21,31 @@ it('renders <Menu links /> without throwing', () => {
const links = [
{
name: 'summary',
pathname: '/instances/:name/summary'
pathname: '/:name/summary'
},
{
name: 'tags',
pathname: '/instances/:name/tags'
pathname: '/:name/tags'
},
{
name: 'metadata',
pathname: '/instances/:name/metadata'
pathname: '/:name/metadata'
},
{
name: 'networks',
pathname: '/instances/:name/networks'
pathname: '/:name/networks'
},
{
name: 'firewall',
pathname: '/instances/:name/firewall'
pathname: '/:name/firewall'
},
{
name: 'dns',
pathname: '/instances/:name/dns'
pathname: '/:name/dns'
},
{
name: 'snapshots',
pathname: '/instances/:name/snapshots'
pathname: '/:name/snapshots'
}
];

View File

@ -23,31 +23,31 @@ it('<Menu links />', async () => {
const links = [
{
name: 'summary',
pathname: '/instances/:name/summary'
pathname: '/:name/summary'
},
{
name: 'tags',
pathname: '/instances/:name/tags'
pathname: '/:name/tags'
},
{
name: 'metadata',
pathname: '/instances/:name/metadata'
pathname: '/:name/metadata'
},
{
name: 'networks',
pathname: '/instances/:name/networks'
pathname: '/:name/networks'
},
{
name: 'firewall',
pathname: '/instances/:name/firewall'
pathname: '/:name/firewall'
},
{
name: 'dns',
pathname: '/instances/:name/dns'
pathname: '/:name/dns'
},
{
name: 'snapshots',
pathname: '/instances/:name/snapshots'
pathname: '/:name/snapshots'
}
];

View File

@ -30,12 +30,20 @@ const Link = styled.a`
export default () => (
<List>
<ListItem>
<Link href="https://www.joyent.com/about/policies" target="_blank">
<Link
href="https://www.joyent.com/about/policies"
target="__blank"
rel="noopener noreferrer"
>
Policies
</Link>
</ListItem>
<ListItem>
<Link href="https://www.joyent.com/networking-and-security/security-compliance">
<Link
href="https://www.joyent.com/networking-and-security/security-compliance"
target="__blank"
rel="noopener noreferrer"
>
Compliance
</Link>
</ListItem>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -447,7 +447,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c24 + button {
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
@ -468,6 +469,11 @@ Array [
display: inline-block;
}
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
.c22 {
box-sizing: border-box;
display: inline-block;
@ -1562,7 +1568,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -1570,6 +1577,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -2052,7 +2064,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -2060,6 +2073,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -2423,7 +2441,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c25 + button {
.c25 + button,
.c25 + a {
margin-left: 0.375rem;
}
@ -2444,6 +2463,11 @@ Array [
display: inline-block;
}
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
.c23 {
box-sizing: border-box;
display: inline-block;
@ -3556,7 +3580,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c25 + button {
.c25 + button,
.c25 + a {
margin-left: 0.375rem;
}
@ -3577,6 +3602,11 @@ Array [
display: inline-block;
}
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
.c23 {
box-sizing: border-box;
display: inline-block;
@ -4960,7 +4990,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c25 + button {
.c25 + button,
.c25 + a {
margin-left: 0.375rem;
}
@ -4981,6 +5012,11 @@ Array [
display: inline-block;
}
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
.c23 {
box-sizing: border-box;
display: inline-block;
@ -6112,7 +6148,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c25 + button {
.c25 + button,
.c25 + a {
margin-left: 0.375rem;
}
@ -6133,6 +6170,11 @@ Array [
display: inline-block;
}
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
.c23 {
box-sizing: border-box;
display: inline-block;
@ -7264,7 +7306,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -7272,6 +7315,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;

View File

@ -2278,7 +2278,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -2286,6 +2287,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -2852,7 +2858,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -2860,6 +2867,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;

View File

@ -449,7 +449,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -457,6 +458,11 @@ Array [
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -1506,7 +1512,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -1514,6 +1521,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -2005,7 +2017,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -2013,6 +2026,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -2647,7 +2665,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -2655,6 +2674,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;

View File

@ -171,7 +171,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -192,6 +193,11 @@ Array [
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -1375,7 +1381,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -1396,6 +1403,11 @@ Array [
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -2359,7 +2371,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -2367,6 +2380,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -2798,7 +2816,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -2806,6 +2825,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -3237,7 +3261,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -3258,6 +3283,11 @@ Array [
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -4221,7 +4251,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -4229,6 +4260,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -4563,7 +4599,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c24 + button {
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
@ -4584,6 +4621,11 @@ Array [
display: inline-block;
}
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
.c22 {
box-sizing: border-box;
display: inline-block;
@ -5577,7 +5619,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -5585,6 +5628,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -5919,7 +5967,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c24 + button {
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
@ -5940,6 +5989,11 @@ Array [
display: inline-block;
}
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
.c22 {
box-sizing: border-box;
display: inline-block;
@ -6933,7 +6987,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -6941,6 +6996,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;
@ -7200,7 +7260,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c23 + button {
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
@ -7221,6 +7282,11 @@ Array [
display: inline-block;
}
.c22 + button,
.c22 + a {
margin-left: 0.375rem;
}
.c21 {
box-sizing: border-box;
display: inline-block;
@ -8184,7 +8250,8 @@ Array [
outline: 0.0625rem dotted ButtonText;
}
.c3 + button {
.c3 + button,
.c3 + a {
margin-left: 0.375rem;
}
@ -8192,6 +8259,11 @@ Array [
display: inline-block;
}
.c2 + button,
.c2 + a {
margin-left: 0.375rem;
}
.c1 {
box-sizing: border-box;
display: inline-block;

View File

@ -158,7 +158,7 @@ export default compose(
})),
connect(null, (dispatch, { affinityRules = [], history }) => ({
handleEdit: () => {
return history.push(`/instances/~create/affinity`);
return history.push(`/~create/affinity${history.location.search}`);
},
handleAddAffinityRules: ({ ...rule }) => {
const toggleToClosed = set({

View File

@ -162,9 +162,9 @@ export default compose(
connect(null, (dispatch, { history, cnsEnabled, serviceNames = [] }) => ({
handleNext: () => {
dispatch(set({ name: `${CNS_FORM}-proceeded`, value: true }));
return history.push(`/instances/~create/affinity`);
return history.push(`/~create/affinity${history.location.search}`);
},
handleEdit: () => history.push(`/instances/~create/cns`),
handleEdit: () => history.push(`/~create/cns${history.location.search}`),
handleToggleCnsEnabled: ({ target }) =>
dispatch(set({ name: `${CNS_FORM}-enabled`, value: !cnsEnabled })),
handleAddService: ({ name }) => {

View File

@ -165,10 +165,10 @@ export default compose(
set({ name: 'create-instance-firewall-proceeded', value: true })
);
return history.push('/instances/~create/cns');
return history.push(`/~create/cns${history.location.search}`);
},
handleEdit: () => {
return history.push('/instances/~create/firewall');
return history.push(`/~create/firewall${history.location.search}`);
}
})
),

View File

@ -20,10 +20,23 @@ import Animated from '@containers/create-instance/animated';
import Description from '@components/description';
import imageData from '@data/images-map.json';
import GetImages from '@graphql/get-images.gql';
import GetImage from '@graphql/get-image.gql';
const HarcodedImage = image => (
<Fragment>
<Title icon={<InstanceTypeIcon />} collapsed={false}>
Instance type and image
</Title>
<Margin bottom={7}>
<Preview {...image} />
</Margin>
</Fragment>
);
const ImageContainer = ({
expanded,
proceeded,
queryImage,
image = {},
handleNext,
handleEdit,
@ -32,7 +45,11 @@ const ImageContainer = ({
images,
vms,
step
}) => (
}) => queryImage ? (
<Fragment>
<HarcodedImage {...queryImage} />
</Fragment>
) : (
<Fragment>
<Title
id={step}
@ -119,9 +136,10 @@ export default compose(
handleNext: () => {
dispatch(set({ name: 'create-instance-image-proceeded', value: true }));
return history.push(`/instances/~create/package`);
return history.push(`/~create/package${history.location.search}`);
},
handleEdit: () => history.push(`/instances/~create/image`),
handleEdit: () =>
history.push(`/~create/image${history.location.search}`),
handleSelectLatest: ({ versions }) => {
const id = versions[0].id;
return dispatch(change('create-instance-image', 'image', id));
@ -130,9 +148,13 @@ export default compose(
),
graphql(GetImages, {
props: ({ ownProps, data }) => {
const { image = '' } = ownProps;
const { image = '', query } = ownProps;
const { loading = false, images = [] } = data;
const queryImage = query.image
? find(images, ['name', query.image])
: null;
const values = images
.reduce((acc, img) => {
const isVm = !includes(img.type, 'DATASET');
@ -186,6 +208,7 @@ export default compose(
return {
loading,
images: values,
queryImage,
image: {
...selected,
isVm: !includes(selected.type || '', 'DATASET')

View File

@ -1,4 +1,5 @@
/* eslint-disable camelcase */
import React from 'react';
import { Margin } from 'styled-components-spacing';
import ReduxForm from 'declarative-redux-form';
@ -8,6 +9,7 @@ import { destroyAll } from 'react-redux-values';
import { graphql, compose } from 'react-apollo';
import intercept from 'apr-intercept';
import constantCase from 'constant-case';
import queryString from 'query-string';
import get from 'lodash.get';
import omit from 'lodash.omit';
import uniqBy from 'lodash.uniqby';
@ -29,23 +31,43 @@ import parseError from '@state/parse-error';
const CREATE_FORM = 'CREATE-INSTANCE';
const CreateInstance = ({ step, disabled, handleSubmit, history, match }) => (
const CreateInstance = ({
step,
disabled,
handleSubmit,
history,
match,
query
}) => (
<ViewContainer>
<Margin top={4} bottom={4}>
<H2>Create Instances</H2>
</Margin>
{query.image ? (
<Image
history={history}
match={match}
query={query}
step="image"
expanded={step === 'image'}
/>
) : null}
<Name
history={history}
match={match}
query={query}
step="name"
expanded={step === 'name'}
/>
<Image
history={history}
match={match}
step="image"
expanded={step === 'image'}
/>
{!query.image ? (
<Image
history={history}
match={match}
query={query}
step="image"
expanded={step === 'image'}
/>
) : null}
<Package
history={history}
match={match}
@ -105,7 +127,8 @@ const CreateInstance = ({ step, disabled, handleSubmit, history, match }) => (
export default compose(
graphql(CreateInstanceMutation, { name: 'createInstance' }),
connect(({ form, values }, { match }) => {
connect(({ form, values }, { match, location }) => {
const query = queryString.parse(location.search);
const FORM_NAME = 'create-instance-name';
const step = get(match, 'params.step', 'name');
const nameFilled = get(form, `${FORM_NAME}.values.name`, '');
@ -117,7 +140,11 @@ export default compose(
);
if (disabled) {
return { disabled, step };
return {
query,
disabled,
step
};
}
const name = get(
@ -162,6 +189,7 @@ export default compose(
}
return {
query,
forms: Object.keys(form), // improve this
name,
pkg,
@ -265,7 +293,7 @@ export default compose(
dispatch([destroyAll(), forms.map(name => destroy(name))]);
history.push(`/instances/${res.data.createMachine.name}`);
history.push(`/${res.data.createMachine.name}`);
}
};
})

View File

@ -157,10 +157,10 @@ export default compose(
set({ name: 'create-instance-metadata-proceeded', value: true })
);
return history.push('/instances/~create/user-script');
return history.push(`/~create/user-script${history.location.search}`);
},
handleEdit: () => {
return history.push(`/instances/~create/metadata`);
return history.push(`/~create/metadata${history.location.search}`);
},
handleAddMetadata: value => {
const toggleToClosed = set({

View File

@ -114,7 +114,7 @@ export default compose(
name
};
},
(dispatch, { history }) => ({
(dispatch, { history, query }) => ({
shouldAsyncValidate: ({ trigger }) => trigger === 'submit',
handleAsyncValidation: async ({ name }) => {
const sanitized = punycode.encode(name).replace(/-$/, '');
@ -160,10 +160,13 @@ export default compose(
},
handleNext: () => {
dispatch(set({ name: 'create-instance-name-proceeded', value: true }));
return history.push(`/instances/~create/image`);
return history.push(
`/~create/${query.image ? 'package' : 'image'}${
history.location.search
}`
);
},
handleEdit: () => history.push(`/instances/~create/name`),
handleEdit: () => history.push(`/~create/name${history.location.search}`),
handleRandomize: async () => {
dispatch(
set({ name: 'create-instance-name-randomizing', value: true })

View File

@ -165,10 +165,10 @@ export default compose(
set({ name: 'create-instance-networks-proceeded', value: true })
);
return history.push('/instances/~create/firewall');
return history.push(`/~create/firewall${history.location.search}`);
},
handleEdit: () => {
return history.push('/instances/~create/networks');
return history.push(`/~create/networks${history.location.search}`);
},
setInfoExpanded: (id, expanded) => {
return dispatch(

View File

@ -228,9 +228,10 @@ export default compose(
set({ name: 'create-instance-package-proceeded', value: true })
);
return history.push('/instances/~create/tags');
return history.push(`/~create/tags${history.location.search}`);
},
handleEdit: () => history.push('/instances/~create/package'),
handleEdit: () =>
history.push(`/~create/package${history.location.search}`),
handleResetFilters: () => {
dispatch(destroy(`${FORM_NAME}-filters`));
},

View File

@ -137,10 +137,10 @@ export default compose(
handleNext: () => {
dispatch(set({ name: 'create-instance-tags-proceeded', value: true }));
return history.push(`/instances/~create/metadata`);
return history.push(`/~create/metadata${history.location.search}`);
},
handleEdit: () => {
return history.push(`/instances/~create/tags`);
return history.push(`/~create/tags${history.location.search}`);
},
handleAddTag: value => {
const toggleToClosed = set({

View File

@ -116,13 +116,14 @@ export default compose(
};
},
(dispatch, { history }) => ({
handleEdit: () => history.push(`/instances/~create/user-script`),
handleEdit: () =>
history.push(`/~create/user-script${history.location.search}`),
handleNext: () => {
dispatch(
set({ name: 'create-instance-user-script-proceeded', value: true })
);
return history.push(`/instances/~create/networks`);
return history.push(`/~create/networks${history.location.search}`);
},
handleChangeOpenForm: value => {
return dispatch([

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -67,7 +67,8 @@ exports[`renders <Cns /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c24 + button {
.c24 + button,
.c24 + a {
margin-left: 0.375rem;
}
@ -82,6 +83,11 @@ exports[`renders <Cns /> without throwing 1`] = `
display: inline-block;
}
.c23 + button,
.c23 + a {
margin-left: 0.375rem;
}
.c22 {
box-sizing: border-box;
display: inline-block;
@ -1226,7 +1232,8 @@ exports[`renders <Cns hostnames /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c33 + button {
.c33 + button,
.c33 + a {
margin-left: 0.375rem;
}
@ -1245,6 +1252,11 @@ exports[`renders <Cns hostnames /> without throwing 1`] = `
display: inline-block;
}
.c32 + button,
.c32 + a {
margin-left: 0.375rem;
}
.c31 {
box-sizing: border-box;
display: inline-block;
@ -3028,7 +3040,8 @@ exports[`renders <Cns loadingError /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c29 + button {
.c29 + button,
.c29 + a {
margin-left: 0.375rem;
}
@ -3052,6 +3065,11 @@ exports[`renders <Cns loadingError /> without throwing 1`] = `
display: inline-block;
}
.c28 + button,
.c28 + a {
margin-left: 0.375rem;
}
.c27 {
box-sizing: border-box;
display: inline-block;
@ -3733,7 +3751,8 @@ exports[`renders <Cns mutating /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c38 + button {
.c38 + button,
.c38 + a {
margin-left: 0.375rem;
}
@ -3752,6 +3771,11 @@ exports[`renders <Cns mutating /> without throwing 1`] = `
display: inline-block;
}
.c37 + button,
.c37 + a {
margin-left: 0.375rem;
}
.c36 {
box-sizing: border-box;
display: inline-block;
@ -5466,7 +5490,8 @@ exports[`renders <Cns mutationError /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c29 + button {
.c29 + button,
.c29 + a {
margin-left: 0.375rem;
}
@ -5490,6 +5515,11 @@ exports[`renders <Cns mutationError /> without throwing 1`] = `
display: inline-block;
}
.c28 + button,
.c28 + a {
margin-left: 0.375rem;
}
.c27 {
box-sizing: border-box;
display: inline-block;
@ -6332,7 +6362,8 @@ exports[`renders <Cns services /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c30 + button {
.c30 + button,
.c30 + a {
margin-left: 0.375rem;
}
@ -6352,6 +6383,11 @@ exports[`renders <Cns services /> without throwing 1`] = `
display: inline-block;
}
.c29 + button,
.c29 + a {
margin-left: 0.375rem;
}
.c28 {
box-sizing: border-box;
display: inline-block;

View File

@ -42,7 +42,8 @@ exports[`renders <List /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c12 + button {
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
@ -131,6 +132,11 @@ exports[`renders <List /> without throwing 1`] = `
display: inline-block;
}
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
.c10 {
box-sizing: border-box;
display: inline-block;
@ -1303,7 +1309,8 @@ exports[`renders <List error /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c12 + button {
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
@ -1401,6 +1408,11 @@ exports[`renders <List error /> without throwing 1`] = `
display: inline-block;
}
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
.c10 {
box-sizing: border-box;
display: inline-block;
@ -2627,7 +2639,8 @@ exports[`renders <List instances /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c12 + button {
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
@ -2726,6 +2739,11 @@ exports[`renders <List instances /> without throwing 1`] = `
display: inline-block;
}
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
.c10 {
box-sizing: border-box;
display: inline-block;
@ -3726,7 +3744,7 @@ exports[`renders <List instances /> without throwing 1`] = `
>
<a
className="c34 c35 c36"
to="/instances/2252839a"
to="/2252839a"
>
2252839a
</a>
@ -3853,7 +3871,7 @@ exports[`renders <List instances /> without throwing 1`] = `
>
<a
className="c34 c35 c36"
to="/instances/f1bd1730"
to="/f1bd1730"
>
f1bd1730
</a>
@ -3974,7 +3992,8 @@ exports[`renders <List instances selected /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c12 + button {
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
@ -4073,6 +4092,11 @@ exports[`renders <List instances selected /> without throwing 1`] = `
display: inline-block;
}
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
.c10 {
box-sizing: border-box;
display: inline-block;
@ -5789,7 +5813,7 @@ exports[`renders <List instances selected /> without throwing 1`] = `
>
<a
className="c34 c35 c36"
to="/instances/2252839a"
to="/2252839a"
>
2252839a
</a>
@ -5916,7 +5940,7 @@ exports[`renders <List instances selected /> without throwing 1`] = `
>
<a
className="c34 c35 c36"
to="/instances/f1bd1730"
to="/f1bd1730"
>
f1bd1730
</a>
@ -6357,7 +6381,8 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c12 + button {
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
@ -6456,6 +6481,11 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
display: inline-block;
}
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
.c10 {
box-sizing: border-box;
display: inline-block;
@ -8172,7 +8202,7 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
>
<a
className="c34 c35 c36"
to="/instances/2252839a"
to="/2252839a"
>
2252839a
</a>
@ -8299,7 +8329,7 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
>
<a
className="c34 c35 c36"
to="/instances/f1bd1730"
to="/f1bd1730"
>
f1bd1730
</a>
@ -8740,7 +8770,8 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
outline: 0.0625rem dotted ButtonText;
}
.c12 + button {
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
@ -8839,6 +8870,11 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
display: inline-block;
}
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
.c10 {
box-sizing: border-box;
display: inline-block;
@ -10768,7 +10804,7 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
>
<a
className="c34 c35 c36"
to="/instances/2252839a"
to="/2252839a"
>
2252839a
</a>
@ -10895,7 +10931,7 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
>
<a
className="c34 c35 c36"
to="/instances/f1bd1730"
to="/f1bd1730"
>
f1bd1730
</a>
@ -11329,7 +11365,8 @@ exports[`renders <List loading /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c12 + button {
.c12 + button,
.c12 + a {
margin-left: 0.375rem;
}
@ -11407,6 +11444,11 @@ exports[`renders <List loading /> without throwing 1`] = `
display: inline-block;
}
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
.c10 {
box-sizing: border-box;
display: inline-block;

View File

@ -38,7 +38,8 @@ exports[`renders <Metadata /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -46,6 +47,11 @@ exports[`renders <Metadata /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;
@ -509,7 +515,8 @@ exports[`renders <Metadata addOpen /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -530,6 +537,11 @@ exports[`renders <Metadata addOpen /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;
@ -1901,7 +1913,8 @@ exports[`renders <Metadata error /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -1918,6 +1931,11 @@ exports[`renders <Metadata error /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;
@ -2422,7 +2440,8 @@ exports[`renders <Metadata loading /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -2500,6 +2519,11 @@ exports[`renders <Metadata loading /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;
@ -2985,7 +3009,8 @@ exports[`renders <Metadata metadata /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -3059,6 +3084,11 @@ exports[`renders <Metadata metadata /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;

View File

@ -39,7 +39,8 @@ exports[`renders <Tags /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -47,6 +48,11 @@ exports[`renders <Tags /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;
@ -526,7 +532,8 @@ exports[`renders <Tags addOpen /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -534,6 +541,11 @@ exports[`renders <Tags addOpen /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;
@ -1896,7 +1908,8 @@ exports[`renders <Tags editable /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -1904,6 +1917,11 @@ exports[`renders <Tags editable /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;
@ -2383,7 +2401,8 @@ exports[`renders <Tags editing /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -2391,6 +2410,11 @@ exports[`renders <Tags editing /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c34 {
box-sizing: border-box;
display: inline-block;
@ -3806,7 +3830,8 @@ exports[`renders <Tags editing.removing /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -3867,6 +3892,11 @@ exports[`renders <Tags editing.removing /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c34 {
box-sizing: border-box;
display: inline-block;
@ -5300,7 +5330,8 @@ exports[`renders <Tags error /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -5308,6 +5339,11 @@ exports[`renders <Tags error /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;
@ -5769,7 +5805,8 @@ exports[`renders <Tags loading /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -5847,6 +5884,11 @@ exports[`renders <Tags loading /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;
@ -6299,7 +6341,8 @@ exports[`renders <Tags tags /> without throwing 1`] = `
outline: 0.0625rem dotted ButtonText;
}
.c11 + button {
.c11 + button,
.c11 + a {
margin-left: 0.375rem;
}
@ -6307,6 +6350,11 @@ exports[`renders <Tags tags /> without throwing 1`] = `
display: inline-block;
}
.c10 + button,
.c10 + a {
margin-left: 0.375rem;
}
.c9 {
box-sizing: border-box;
display: inline-block;

View File

@ -55,6 +55,7 @@ export const List = ({
submitting,
handleAction,
toggleSelectAll,
handleCreateImage,
handleSortBy,
history
}) => {
@ -110,6 +111,7 @@ export const List = ({
key={id}
id={id}
{...rest}
onCreateImage={() => handleCreateImage(rest)}
onStart={() => handleStart([{ id }])}
onStop={() => handleStop([{ id }])}
onReboot={() => handleReboot([{ id }])}
@ -153,7 +155,7 @@ export const List = ({
searchLabel="Filter instances"
searchable={!_loading}
actionLabel="Create Instance"
onActionClick={() => history.push(`/instances/~create`)}
onActionClick={() => history.push(`/~create`)}
/>
)}
</ReduxForm>
@ -260,6 +262,8 @@ export default compose(
};
},
(dispatch, { refetch, ...ownProps }) => ({
handleCreateImage: ({ name }) =>
window.open(`http://localhost:3070/~create/${name}`, '_blank').focus(),
handleSortBy: ({ sortBy: currentSortBy, sortOrder }) => newSortBy => {
// sort prop is the same, toggle
if (currentSortBy === newSortBy) {

View File

@ -167,7 +167,6 @@ export default compose(
props: ({ data: { loading, error, variables, refetch, ...rest } }) => {
const { name } = variables;
const instance = find(get(rest, 'machines', []), ['name', name]);
const snapshots = get(instance, 'snapshots', []);
const index = GenIndex(
@ -312,6 +311,8 @@ export default compose(
);
}
await refetch();
dispatch(
set({
name: `snapshots-create-open`,

View File

@ -138,7 +138,7 @@ export default compose(
if (!err && action === 'remove') {
const { history } = ownProps;
return history.push(`/instances/`);
return history.push(`/`);
}
// after mutation, sets loading back to false

View File

@ -11,14 +11,14 @@ export default ({ match }) => {
const links = [
{
name: 'Instances',
pathname: '/instances'
pathname: '/'
}
]
.concat(
instance && [
{
name: paramCase(instance),
pathname: `/instances/${instance}`
pathname: `/${instance}`
}
]
)

View File

@ -10,7 +10,7 @@ export default connect((state, { match }) => {
const links = sections.map(({ name, pathname }) => ({
name,
pathname: `/instances/${instanceSlug}/${pathname}`
pathname: `/${instanceSlug}/${pathname}`
}));
return {

View File

@ -0,0 +1,9 @@
query Image($name: String) {
images(name: $name) {
id
name
os
version
type
}
}

View File

@ -25,76 +25,46 @@ export default () => (
<PageContainer>
{/* Breadcrumb */}
<Switch>
<Route
path="/instances/~create/:section?"
exact
component={Breadcrumb}
/>
<Route
path="/instances/~:action/:instance?"
exact
component={Breadcrumb}
/>
<Route path="/instances/:instance?" component={Breadcrumb} />
<Route path="/~create/:section?" exact component={Breadcrumb} />
<Route path="/~:action/:instance?" exact component={Breadcrumb} />
<Route path="/:instance?" component={Breadcrumb} />
</Switch>
{/* Menu */}
<Switch>
<Route path="/instances/~:action/:id?" exact component={Menu} />
<Route path="/instances/:instance?/:section?" component={Menu} />
<Route path="/~:action/:id?" exact component={Menu} />
<Route path="/:instance?/:section?" component={Menu} />
</Switch>
{/* Instances List */}
<Switch>
<Route path="/instances" exact component={Instances} />
<Route path="/" exact component={Instances} />
</Switch>
{/* Instance Sections */}
<Switch>
<Route path="/instances/~:action" component={() => null} />
<Route path="/~:action" component={() => null} />
<Route path="/:instance/summary" exact component={InstanceSummary} />
<Route path="/:instance/tags" exact component={InstanceTags} />
<Route path="/:instance/metadata" exact component={InstanceMetadata} />
<Route path="/:instance/networks" exact component={InstanceNetworks} />
<Route path="/:instance/firewall" exact component={InstanceFirewall} />
<Route
path="/instances/:instance/summary"
exact
component={InstanceSummary}
/>
<Route
path="/instances/:instance/tags"
exact
component={InstanceTags}
/>
<Route
path="/instances/:instance/metadata"
exact
component={InstanceMetadata}
/>
<Route
path="/instances/:instance/networks"
exact
component={InstanceNetworks}
/>
<Route
path="/instances/:instance/firewall"
exact
component={InstanceFirewall}
/>
<Route
path="/instances/:instance/snapshots"
path="/:instance/snapshots"
exact
component={InstanceSnapshots}
/>
<Route path="/instances/:instance/cns" exact component={InstanceCns} />
<Route path="/:instance/cns" exact component={InstanceCns} />
<Route
path="/instances/:instance/user-script"
path="/:instance/user-script"
exact
component={InstanceUserScript}
/>
<Route
path="/instances/:instance"
path="/:instance"
exact
component={({ match }) => (
<Redirect
to={`/instances/${get(match, 'params.instance')}/summary`}
/>
<Redirect to={`/${get(match, 'params.instance')}/summary`} />
)}
/>
</Switch>
@ -103,14 +73,14 @@ export default () => (
<Switch>
{/* Create Instance */}
<Route
path="/instances/~create/"
path="/~create/"
exact
component={() => <Redirect to="/instances/~create/name" />}
component={({ match, location }) => (
<Redirect to={`/~create/name${location.search}`} />
)}
/>
<Route path="/instances/~create/:step" component={CreateInstance} />
<Route path="/~create/:step" component={CreateInstance} />
</Switch>
<Route path="/" exact component={() => <Redirect to="/instances" />} />
<Footer />
</PageContainer>
</BrowserRouter>

View File

@ -22,6 +22,11 @@ exports[`Button Default Button 1`] = `
display: inline-block;
}
.c1 + button,
.c1 + a {
margin-left: 0.375rem;
}
.c0 {
box-sizing: border-box;
display: inline-block;
@ -128,6 +133,11 @@ exports[`Button Disabled Button 1`] = `
display: inline-block;
}
.c1 + button,
.c1 + a {
margin-left: 0.375rem;
}
.c0 {
box-sizing: border-box;
display: inline-block;
@ -249,6 +259,11 @@ exports[`Button Error Button 1`] = `
display: inline-block;
}
.c1 + button,
.c1 + a {
margin-left: 0.375rem;
}
.c0 {
box-sizing: border-box;
display: inline-block;
@ -378,6 +393,11 @@ exports[`Button Loading Button 1`] = `
display: inline-block;
}
.c1 + button,
.c1 + a {
margin-left: 0.375rem;
}
.c0 {
box-sizing: border-box;
display: inline-block;
@ -501,6 +521,11 @@ exports[`Button Secondary Button 1`] = `
display: inline-block;
}
.c1 + button,
.c1 + a {
margin-left: 0.375rem;
}
.c0 {
box-sizing: border-box;
display: inline-block;

View File

@ -12,7 +12,8 @@ import StatusLoader from '../status-loader';
const StyledButton = NButton.extend`
min-width: ${remcalc(120)};
& + button {
& + button,
& + a {
margin-left: ${remcalc(6)};
}
`;
@ -21,6 +22,11 @@ const InlineAnchor = styled(({ component, children, ...rest }) =>
React.createElement(component, rest, children)
)`
display: inline-block;
& + button,
& + a {
margin-left: ${remcalc(6)};
}
`;
/**

View File

@ -4938,8 +4938,8 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.4,
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
graphi@^5.3.0:
version "5.3.1"
resolved "https://registry.yarnpkg.com/graphi/-/graphi-5.3.1.tgz#83715e0a8c433705fe94ca2d5a98a375a309873f"
version "5.3.2"
resolved "https://registry.yarnpkg.com/graphi/-/graphi-5.3.2.tgz#ec427db244f576845163dd30dff780366d18933d"
dependencies:
boom "7.x.x"
graphql "0.12.x"
@ -8620,6 +8620,14 @@ query-string@^4.1.0:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
query-string@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.0.tgz#9583b15fd1307f899e973ed418886426a9976469"
dependencies:
decode-uri-component "^0.2.0"
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
querystring-es3@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"