feat(instances): route objects id

fixes #1329
This commit is contained in:
Sara Vieira 2018-03-21 17:35:51 +00:00 committed by Sérgio Ramos
parent fab0bbfcc3
commit 7f0658e246
44 changed files with 245 additions and 263 deletions

View File

@ -17,7 +17,7 @@
}, },
"dependencies": { "dependencies": {
"brule": "^3.1.0", "brule": "^3.1.0",
"cloudapi-gql": "^7.1.1", "cloudapi-gql": "^7.1.3",
"hapi": "^17.2.0", "hapi": "^17.2.0",
"hapi-triton-auth": "^2.0.0", "hapi-triton-auth": "^2.0.0",
"inert": "^5.1.0", "inert": "^5.1.0",

View File

@ -1,10 +1,10 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import styled from 'styled-components'; import styled from 'styled-components';
import remcalc from 'remcalc';
import { Field } from 'redux-form'; import { Field } from 'redux-form';
import Flex from 'styled-flex-component'; import Flex from 'styled-flex-component';
import { Padding, Margin } from 'styled-components-spacing'; import { Padding, Margin } from 'styled-components-spacing';
import remcalc from 'remcalc';
import { import {
Card, Card,
@ -50,7 +50,7 @@ const Type = styled(Margin)`
`; `;
const Content = styled(Padding)` const Content = styled(Padding)`
max-width: calc(100% - 48px); max-width: calc(100% - ${remcalc(48)});
overflow: hidden; overflow: hidden;
`; `;
@ -64,13 +64,19 @@ const DividerContainer = styled(Margin)`
`; `;
const Actions = styled(Flex)` const Actions = styled(Flex)`
width: 48px; width: ${remcalc(48)};
height: 48px; height: ${remcalc(48)};
min-width: 48px; min-width: ${remcalc(48)};
`;
const ActionsWrapper = styled(Flex)`
height: 100%;
border-left: ${remcalc(1)} solid ${props => props.theme.grey};
`; `;
export const Image = ({ export const Image = ({
name, name,
id,
os, os,
version, version,
type, type,
@ -79,7 +85,7 @@ export const Image = ({
onCreateInstance onCreateInstance
}) => ( }) => (
<Margin bottom={3}> <Margin bottom={3}>
<CardAnchor to={`/images/${name}`} component={Link}> <CardAnchor to={`/images/${id}`} component={Link}>
<Card radius> <Card radius>
{removing ? ( {removing ? (
<Padding all={2}> <Padding all={2}>
@ -96,7 +102,7 @@ export const Image = ({
height: '24' height: '24'
})} })}
</Margin> </Margin>
<A to={`/images/${name}/summary`} component={Link}> <A to={`/images/${id}/summary`} component={Link}>
{name} {name}
</A> </A>
</Flex> </Flex>
@ -116,11 +122,10 @@ export const Image = ({
</Content> </Content>
<PopoverContainer clickable> <PopoverContainer clickable>
<Actions> <Actions>
<PopoverTarget <PopoverTarget box>
box <ActionsWrapper alignCenter justifyCenter>
style={{ borderLeft: '1px solid #D8D8D8' }} <ActionsIcon />
> </ActionsWrapper>
<ActionsIcon />
</PopoverTarget> </PopoverTarget>
<Popover placement="bottom"> <Popover placement="bottom">
<PopoverItem disabled={false} onClick={onCreateInstance}> <PopoverItem disabled={false} onClick={onCreateInstance}>

View File

@ -117,7 +117,7 @@ export default withTheme(({ theme = {}, onRemove, removing, ...image }) => (
<Button <Button
type="button" type="button"
href={`${GLOBAL.origin}/instances/~create/?image=${ href={`${GLOBAL.origin}/instances/~create/?image=${
image.name image.id
}`} }`}
target="__blank" target="__blank"
rel="noopener noreferrer" rel="noopener noreferrer"

View File

@ -97,20 +97,15 @@ export default compose(
options: ({ match }) => ({ options: ({ match }) => ({
ssr: false, ssr: false,
variables: { variables: {
name: get(match, 'params.instance') id: get(match, 'params.instance')
} }
}), }),
props: ({ data: { loading, error, variables, ...rest } }) => { props: ({ data: { loading, error, machine, variables, ...rest } }) => {
const notFoundMsg = `Instance "${variables.name}" not found!`; const notFoundMsg = `Instance "${variables.name}" not found!`;
const inst = find(get(rest, 'machines.results', []), [ const notFound = !loading && !machine ? notFoundMsg : false;
'name',
variables.name
]);
const notFound = !loading && !inst ? notFoundMsg : false;
return { return {
instance: inst, instance: machine,
loadingError: error ? parseError(error) : notFound, loadingError: error ? parseError(error) : notFound,
loading loading
}; };
@ -190,7 +185,7 @@ export default compose(
const { data } = res; const { data } = res;
const { createImageFromMachine } = data; const { createImageFromMachine } = data;
history.push(`/images/${createImageFromMachine.name}`); history.push(`/images/${createImageFromMachine.id}`);
} }
}; };
}) })

View File

@ -9,12 +9,12 @@ const SECTIONS = [
]; ];
export default ({ match }) => { export default ({ match }) => {
const imageSlug = get(match, 'params.image'); const imageId = get(match, 'params.image');
const sections = imageSlug !== '~create' ? SECTIONS : []; const sections = imageId !== '~create' ? SECTIONS : [];
const links = sections.map(({ name, pathname }) => ({ const links = sections.map(({ name, pathname }) => ({
name, name,
pathname: `/images/${imageSlug}/${pathname}` pathname: `/images/${imageId}/${pathname}`
})); }));
return <Menu links={links} />; return <Menu links={links} />;

View File

@ -69,16 +69,17 @@ export default compose(
options: ({ match }) => ({ options: ({ match }) => ({
ssr: false, ssr: false,
variables: { variables: {
name: get(match, 'params.image') id: get(match, 'params.image')
} }
}), }),
props: ({ props: ({ data }) => {
data: { loading = false, error = null, variables, ...rest } const { loading = false, error = null, image } = data;
}) => ({ return {
image: find(get(rest, 'images', []), ['name', variables.name]), image,
loading, loading,
error error
}) };
}
}), }),
connect( connect(
({ values }, ownProps) => { ({ values }, ownProps) => {

View File

@ -129,19 +129,12 @@ export default compose(
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
pollInterval: 1000, pollInterval: 1000,
variables: { variables: {
name: get(match, 'params.image') id: get(match, 'params.image')
} }
}), }),
props: ({ data }) => { props: ({ data }) => {
const { const { loading = false, error = null, image, refetch, ...rest } = data;
loading = false,
error = null,
variables,
refetch,
...rest
} = data;
const image = find(get(rest, 'images', []), ['name', variables.name]);
const tags = get(image || {}, 'tags', []); const tags = get(image || {}, 'tags', []);
const index = new Fuse(tags, { const index = new Fuse(tags, {
keys: ['name', 'value'] keys: ['name', 'value']

View File

@ -1,5 +1,5 @@
query image($name: String) { query image($id: ID) {
images(name: $name) { image(id: $id) {
id id
name name
os os

View File

@ -1,8 +1,6 @@
query instance($name: String) { query instance($id: ID) {
machines(name: $name) { machine(id: $id) {
results { id
id name
name
}
} }
} }

View File

@ -1,5 +1,5 @@
query image($name: String) { query image($id: ID) {
images(name: $name) { image(id: $id) {
id id
name name
tags { tags {

View File

@ -4548,12 +4548,15 @@ exports[`renders <Item /> without throwing 1`] = `
-webkit-text-decoration: none; -webkit-text-decoration: none;
text-decoration: none; text-decoration: none;
font-weight: 600; font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: block;
} }
.c20 { .c20 {
width: 3rem;
height: 3rem; height: 3rem;
min-width: 3rem;
} }
@media only screen and (min-width:47.9375rem) { @media only screen and (min-width:47.9375rem) {
@ -4632,7 +4635,7 @@ exports[`renders <Item /> without throwing 1`] = `
> >
<a <a
className="c11 c12 c13" className="c11 c12 c13"
to="/instances/undefined" to="/instances/"
/> />
</td> </td>
<td <td
@ -5067,12 +5070,15 @@ exports[`renders <Item {...item} /> without throwing 1`] = `
-webkit-text-decoration: none; -webkit-text-decoration: none;
text-decoration: none; text-decoration: none;
font-weight: 600; font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: block;
} }
.c20 { .c20 {
width: 3rem;
height: 3rem; height: 3rem;
min-width: 3rem;
} }
@media only screen and (min-width:47.9375rem) { @media only screen and (min-width:47.9375rem) {
@ -5151,7 +5157,7 @@ exports[`renders <Item {...item} /> without throwing 1`] = `
> >
<a <a
className="c11 c12 c13" className="c11 c12 c13"
to="/instances/name" to="/instances/id"
> >
name name
</a> </a>
@ -5588,12 +5594,15 @@ exports[`renders <Item allowedActions /> without throwing 1`] = `
-webkit-text-decoration: none; -webkit-text-decoration: none;
text-decoration: none; text-decoration: none;
font-weight: 600; font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: block;
} }
.c20 { .c20 {
width: 3rem;
height: 3rem; height: 3rem;
min-width: 3rem;
} }
@media only screen and (min-width:47.9375rem) { @media only screen and (min-width:47.9375rem) {
@ -5672,7 +5681,7 @@ exports[`renders <Item allowedActions /> without throwing 1`] = `
> >
<a <a
className="c11 c12 c13" className="c11 c12 c13"
to="/instances/undefined" to="/instances/"
/> />
</td> </td>
<td <td
@ -6106,6 +6115,11 @@ exports[`renders <Item mutating /> without throwing 1`] = `
-webkit-text-decoration: none; -webkit-text-decoration: none;
text-decoration: none; text-decoration: none;
font-weight: 600; font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: block;
} }
@media only screen and (min-width:47.9375rem) { @media only screen and (min-width:47.9375rem) {
@ -6184,7 +6198,7 @@ exports[`renders <Item mutating /> without throwing 1`] = `
> >
<a <a
className="c11 c12 c13" className="c11 c12 c13"
to="/instances/undefined" to="/instances/"
/> />
</td> </td>
<td <td

View File

@ -3569,7 +3569,7 @@ exports[`renders <Summary instance /> without throwing 1`] = `
<a <a
className="c18 c19 c20 c21" className="c18 c19 c20 c21"
data-ui-button="true" data-ui-button="true"
href="http://localhost/images/~create/undefined" href="http://localhost/images/~create/2252839a-e698-ceec-afac-9549ad0c6624"
icon={true} icon={true}
rel="noopener noreferrer" rel="noopener noreferrer"
target="__blank" target="__blank"
@ -5975,7 +5975,7 @@ exports[`renders <Summary instance /> without throwing 2`] = `
<a <a
className="c18 c19 c20 c21" className="c18 c19 c20 c21"
data-ui-button="true" data-ui-button="true"
href="http://localhost/images/~create/undefined" href="http://localhost/images/~create/2252839a-e698-ceec-afac-9549ad0c6624"
icon={true} icon={true}
rel="noopener noreferrer" rel="noopener noreferrer"
target="__blank" target="__blank"

View File

@ -45,6 +45,11 @@ const A = styled(Anchor)`
color: ${props => props.theme.text}; color: ${props => props.theme.text};
text-decoration: none; text-decoration: none;
font-weight: ${props => props.theme.font.weight.semibold}; font-weight: ${props => props.theme.font.weight.semibold};
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: block;
`; `;
const ItemAnchor = styled(Anchor)` const ItemAnchor = styled(Anchor)`
@ -54,9 +59,7 @@ const ItemAnchor = styled(Anchor)`
`; `;
const Actions = styled(Flex)` const Actions = styled(Flex)`
width: ${remcalc(48)};
height: ${remcalc(48)}; height: ${remcalc(48)};
min-width: ${remcalc(48)};
`; `;
export const FetchingItem = () => ( export const FetchingItem = () => (
@ -88,7 +91,7 @@ export const Item = ({
</FormGroup> </FormGroup>
</TableTd> </TableTd>
<TableTd middle left> <TableTd middle left>
<A to={`/instances/${name}`} component={Link}> <A to={`/instances/${id}`} component={Link}>
{name} {name}
</A> </A>
</TableTd> </TableTd>
@ -129,7 +132,7 @@ export const Item = ({
<PopoverDivider /> <PopoverDivider />
<PopoverItem disabled={false} onClick={onCreateImage}> <PopoverItem disabled={false} onClick={onCreateImage}>
<ItemAnchor <ItemAnchor
href={`${GLOBAL.origin}/images/~create/${name}`} href={`${GLOBAL.origin}/images/~create/${id}`}
target="__blank" target="__blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >

View File

@ -142,7 +142,7 @@ export default withTheme(
<Row between="xs"> <Row between="xs">
<Col xs={9}> <Col xs={9}>
<Button <Button
href={`${GLOBAL.origin}/images/~create/${instance.name}`} href={`${GLOBAL.origin}/images/~create/${instance.id}`}
target="__blank" target="__blank"
rel="noopener noreferrer" rel="noopener noreferrer"
secondary secondary

View File

@ -74,7 +74,7 @@ exports[`renders <Menu links /> without throwing 1`] = `
list-style-type: none; list-style-type: none;
padding: 0.8125rem 0rem; padding: 0.8125rem 0rem;
margin: 1.125rem 0 0 0; margin: 1.125rem 0 0 0;
max-height: 50px; max-height: 3.125rem;
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
box-sizing: border-box; box-sizing: border-box;

View File

@ -169,9 +169,9 @@ export default compose(
}) })
), ),
graphql(GetImages, { graphql(GetImages, {
options: () => ({ options: ({ query }) => ({
ssr: false, ssr: false,
variables: { public: true } variables: { public: !query.image }
}), }),
props: ({ ownProps, data }) => { props: ({ ownProps, data }) => {
const { image = '', query } = ownProps; const { image = '', query } = ownProps;
@ -180,7 +180,7 @@ export default compose(
if (query.image) { if (query.image) {
return { return {
loading, loading,
image: find(images, ['name', query.image], {}), image: find(images, ['id', query.image], {}),
hardcoded: true hardcoded: true
}; };
} }

View File

@ -367,7 +367,7 @@ export default compose(
} }
dispatch([destroyAll(), forms.map(name => destroy(name))]); dispatch([destroyAll(), forms.map(name => destroy(name))]);
history.push(`/instances/${res.data.createMachine.name}`); history.push(`/instances/${res.data.createMachine.id}`);
} }
}; };
}) })

View File

@ -3526,12 +3526,15 @@ exports[`renders <List instances /> without throwing 1`] = `
-webkit-text-decoration: none; -webkit-text-decoration: none;
text-decoration: none; text-decoration: none;
font-weight: 600; font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: block;
} }
.c42 { .c42 {
width: 3rem;
height: 3rem; height: 3rem;
min-width: 3rem;
} }
@media only screen and (min-width:48em) { @media only screen and (min-width:48em) {
@ -3800,7 +3803,7 @@ exports[`renders <List instances /> without throwing 1`] = `
> >
<div <div
className="c19 baseline-jVaZNU c19 c4" className="c19 baseline-jVaZNU c19 c4"
name="" name="2252839a"
role="group" role="group"
style={undefined} style={undefined}
> >
@ -3840,9 +3843,7 @@ exports[`renders <List instances /> without throwing 1`] = `
<a <a
className="c34 c35 c36" className="c34 c35 c36"
to="/instances/2252839a" to="/instances/2252839a"
> />
2252839a
</a>
</td> </td>
<td <td
className="c33" className="c33"
@ -3875,7 +3876,7 @@ exports[`renders <List instances /> without throwing 1`] = `
selected={undefined} selected={undefined}
> >
<code> <code>
2252839
</code> </code>
</td> </td>
<td <td
@ -3936,7 +3937,7 @@ exports[`renders <List instances /> without throwing 1`] = `
> >
<div <div
className="c19 baseline-jVaZNU c19 c4" className="c19 baseline-jVaZNU c19 c4"
name="" name="f1bd1730"
role="group" role="group"
style={undefined} style={undefined}
> >
@ -3976,9 +3977,7 @@ exports[`renders <List instances /> without throwing 1`] = `
<a <a
className="c34 c35 c36" className="c34 c35 c36"
to="/instances/f1bd1730" to="/instances/f1bd1730"
> />
f1bd1730
</a>
</td> </td>
<td <td
className="c33" className="c33"
@ -4011,7 +4010,7 @@ exports[`renders <List instances /> without throwing 1`] = `
selected={undefined} selected={undefined}
> >
<code> <code>
f1bd173
</code> </code>
</td> </td>
<td <td
@ -5731,12 +5730,15 @@ exports[`renders <List instances selected /> without throwing 1`] = `
-webkit-text-decoration: none; -webkit-text-decoration: none;
text-decoration: none; text-decoration: none;
font-weight: 600; font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: block;
} }
.c42 { .c42 {
width: 3rem;
height: 3rem; height: 3rem;
min-width: 3rem;
} }
@media only screen and (min-width:48em) { @media only screen and (min-width:48em) {
@ -6105,7 +6107,7 @@ exports[`renders <List instances selected /> without throwing 1`] = `
> >
<a <a
className="c34 c35 c36" className="c34 c35 c36"
to="/instances/2252839a" to="/instances/2252839a-e698-ceec-afac-9549ad0c6624"
> >
2252839a 2252839a
</a> </a>
@ -6241,7 +6243,7 @@ exports[`renders <List instances selected /> without throwing 1`] = `
> >
<a <a
className="c34 c35 c36" className="c34 c35 c36"
to="/instances/f1bd1730" to="/instances/f1bd1730-e8a6-4956-e738-d8e85cc6aa04"
> >
f1bd1730 f1bd1730
</a> </a>
@ -8325,12 +8327,15 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
-webkit-text-decoration: none; -webkit-text-decoration: none;
text-decoration: none; text-decoration: none;
font-weight: 600; font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: block;
} }
.c42 { .c42 {
width: 3rem;
height: 3rem; height: 3rem;
min-width: 3rem;
} }
@media only screen and (min-width:48em) { @media only screen and (min-width:48em) {
@ -8699,7 +8704,7 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
> >
<a <a
className="c34 c35 c36" className="c34 c35 c36"
to="/instances/2252839a" to="/instances/2252839a-e698-ceec-afac-9549ad0c6624"
> >
2252839a 2252839a
</a> </a>
@ -8835,7 +8840,7 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
> >
<a <a
className="c34 c35 c36" className="c34 c35 c36"
to="/instances/f1bd1730" to="/instances/f1bd1730-e8a6-4956-e738-d8e85cc6aa04"
> >
f1bd1730 f1bd1730
</a> </a>
@ -11132,12 +11137,15 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
-webkit-text-decoration: none; -webkit-text-decoration: none;
text-decoration: none; text-decoration: none;
font-weight: 600; font-weight: 600;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: block;
} }
.c42 { .c42 {
width: 3rem;
height: 3rem; height: 3rem;
min-width: 3rem;
} }
@media only screen and (min-width:48em) { @media only screen and (min-width:48em) {
@ -11506,7 +11514,7 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
> >
<a <a
className="c34 c35 c36" className="c34 c35 c36"
to="/instances/2252839a" to="/instances/2252839a-e698-ceec-afac-9549ad0c6624"
> >
2252839a 2252839a
</a> </a>
@ -11642,7 +11650,7 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
> >
<a <a
className="c34 c35 c36" className="c34 c35 c36"
to="/instances/f1bd1730" to="/instances/f1bd1730-e8a6-4956-e738-d8e85cc6aa04"
> >
f1bd1730 f1bd1730
</a> </a>

View File

@ -2485,7 +2485,7 @@ exports[`renders <Summary starting stopping rebooting removing /> without throwi
<a <a
className="c19 c20 c21 c22" className="c19 c20 c21 c22"
data-ui-button="true" data-ui-button="true"
href="http://localhost/images/~create/undefined" href="http://localhost/images/~create/2252839a-e698-ceec-afac-9549ad0c6624"
icon={true} icon={true}
rel="noopener noreferrer" rel="noopener noreferrer"
target="__blank" target="__blank"
@ -4929,7 +4929,7 @@ exports[`renders <Summary starting stopping rebooting removing /> without throwi
<a <a
className="c19 c20 c21 c22" className="c19 c20 c21 c22"
data-ui-button="true" data-ui-button="true"
href="http://localhost/images/~create/undefined" href="http://localhost/images/~create/2252839a-e698-ceec-afac-9549ad0c6624"
icon={true} icon={true}
rel="noopener noreferrer" rel="noopener noreferrer"
target="__blank" target="__blank"

View File

@ -44,11 +44,11 @@ it('renders <List error /> without throwing', () => {
it('renders <List instances /> without throwing', () => { it('renders <List instances /> without throwing', () => {
const instances = [ const instances = [
{ {
name: '2252839a', id: '2252839a',
status: 'RUNNING' status: 'RUNNING'
}, },
{ {
name: 'f1bd1730', id: 'f1bd1730',
status: 'STOPPED' status: 'STOPPED'
} }
]; ];

View File

@ -147,19 +147,16 @@ export default compose(
ssr: false, ssr: false,
variables: { variables: {
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
name: get(match, 'params.instance') id: get(match, 'params.instance')
} }
}), }),
props: ({ data }) => { props: ({ data }) => {
const { loading, error, variables, refetch, ...rest } = data; const { loading, error, machine, refetch } = data;
const { name } = variables; const tags = get(machine, 'tags', []);
const instance = find(get(rest, 'machines.results', []), ['name', name]);
const tags = get(instance, 'tags', []);
return { return {
tags, tags,
instance, instance: machine,
loading, loading,
loadingError: error, loadingError: error,
refetch refetch

View File

@ -8,7 +8,6 @@ import { SubmissionError } from 'redux-form';
import { Margin } from 'styled-components-spacing'; import { Margin } from 'styled-components-spacing';
import remcalc from 'remcalc'; import remcalc from 'remcalc';
import isBoolean from 'lodash.isboolean'; import isBoolean from 'lodash.isboolean';
import find from 'lodash.find';
import get from 'lodash.get'; import get from 'lodash.get';
import { import {
@ -138,22 +137,20 @@ export default compose(
ssr: false, ssr: false,
variables: { variables: {
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
name: get(match, 'params.instance') id: get(match, 'params.instance')
} }
}), }),
props: ({ data }) => { props: ({ data }) => {
const { loading, error, variables, refetch, ...rest } = data; const { loading, error, machine } = data;
const { name } = variables;
const instance = find(get(rest, 'machines.results', []), ['name', name]); const enabled = get(machine, 'firewall_enabled');
const enabled = get(instance, 'firewall_enabled'); const rules = get(machine, 'firewall_rules', []);
const rules = get(instance, 'firewall_rules', []);
return { return {
enabled, enabled,
defaultRules: rules.filter(({ rule_obj = {} }) => rule_obj.isWildcard), defaultRules: rules.filter(({ rule_obj = {} }) => rule_obj.isWildcard),
tagRules: rules.filter(({ rule_obj = {} }) => rule_obj.tags.length), tagRules: rules.filter(({ rule_obj = {} }) => rule_obj.tags.length),
instance, instance: machine,
loading, loading,
loadingError: error loadingError: error
}; };

View File

@ -121,17 +121,15 @@ export const List = ({
total={total} total={total}
> >
{fetching ? <InstanceListFetchingItem /> : null} {fetching ? <InstanceListFetchingItem /> : null}
{(!fetching ? _instances : []).map(({ name, id, ...rest }) => ( {(!fetching ? _instances : []).map(instance => (
<InstanceListItem <InstanceListItem
key={id} key={instance.id}
id={id} {...instance}
name={name} onCreateImage={() => handleCreateImage(instance)}
{...rest} onStart={() => handleStart([instance])}
onCreateImage={() => handleCreateImage(rest)} onStop={() => handleStop([instance])}
onStart={() => handleStart([{ id }])} onReboot={() => handleReboot([instance])}
onStop={() => handleStop([{ id }])} onRemove={() => handleRemove([instance])}
onReboot={() => handleReboot([{ id }])}
onRemove={() => handleRemove([{ id }])}
/> />
))} ))}
</InstanceList> </InstanceList>
@ -299,9 +297,9 @@ export default compose(
}; };
}, },
(dispatch, { refetch, ...ownProps }) => ({ (dispatch, { refetch, ...ownProps }) => ({
handleCreateImage: ({ name }) => { handleCreateImage: ({ id }) => {
return window return window
.open(`${GLOBAL.origin}/images/~create/${name}`, '_blank') .open(`${GLOBAL.origin}/images/~create/${id}`, '_blank')
.focus(); .focus();
}, },
handleSortBy: ({ sortBy: currentSortBy, sortOrder }) => newSortBy => { handleSortBy: ({ sortBy: currentSortBy, sortOrder }) => newSortBy => {

View File

@ -161,14 +161,11 @@ export default compose(
ssr: false, ssr: false,
pollInterval: 1000, pollInterval: 1000,
variables: { variables: {
name: get(match, 'params.instance') id: get(match, 'params.instance')
} }
}), }),
props: ({ data: { loading, error, variables, refetch, ...rest } }) => { props: ({ data: { loading, error, machine, refetch, ...rest } }) => {
const { name } = variables; const values = get(machine, 'metadata', []).filter(
const instance = find(get(rest, 'machines.results', []), ['name', name]);
const values = get(instance, 'metadata', []).filter(
({ name = '' }) => name !== 'user-script' ({ name = '' }) => name !== 'user-script'
); );
@ -188,7 +185,7 @@ export default compose(
return { return {
index, index,
metadata, metadata,
instance, instance: machine,
loading, loading,
error, error,
refetch refetch

View File

@ -82,15 +82,15 @@ export default compose(
graphql(GetNetworks, { graphql(GetNetworks, {
options: ({ match }) => ({ options: ({ match }) => ({
variables: { variables: {
name: get(match, 'params.instance') id: get(match, 'params.instance')
} }
}), }),
props: ({ data }) => { props: ({ data }) => {
const { loading, error, variables } = data; const { loading, error, variables } = data;
const { name } = variables; const { id } = variables;
const machines = get(data, 'machines.results', []); const machines = get(data, 'machines.results', []);
const instance = find(forceArray(machines), ['name', name]); const instance = find(forceArray(machines), ['id', id]);
const values = get(instance, 'networks', []); const values = get(instance, 'networks', []);
const networks = reverse(sortBy(values, 'public')); const networks = reverse(sortBy(values, 'public'));

View File

@ -171,13 +171,11 @@ export default compose(
ssr: false, ssr: false,
pollInterval: 1000, pollInterval: 1000,
variables: { variables: {
name: get(match, 'params.instance') id: get(match, 'params.instance')
} }
}), }),
props: ({ data: { loading, error, variables, refetch, ...rest } }) => { props: ({ data: { loading, error, machine, refetch, ...rest } }) => {
const { name } = variables; const snapshots = get(machine, 'snapshots', []);
const instance = find(get(rest, 'machines.results', []), ['name', name]);
const snapshots = get(instance, 'snapshots', []);
const index = new Fuse(snapshots, { const index = new Fuse(snapshots, {
keys: ['name', 'status', 'created'] keys: ['name', 'status', 'created']
@ -186,7 +184,7 @@ export default compose(
return { return {
index, index,
snapshots, snapshots,
instance, instance: machine,
loading, loading,
error, error,
refetch refetch

View File

@ -4,7 +4,6 @@ import { connect } from 'react-redux';
import { set } from 'react-redux-values'; import { set } from 'react-redux-values';
import { Margin } from 'styled-components-spacing'; import { Margin } from 'styled-components-spacing';
import intercept from 'apr-intercept'; import intercept from 'apr-intercept';
import find from 'lodash.find';
import isArray from 'lodash.isarray'; import isArray from 'lodash.isarray';
import some from 'lodash.some'; import some from 'lodash.some';
import isInteger from 'lodash.isinteger'; import isInteger from 'lodash.isinteger';
@ -142,17 +141,12 @@ export default compose(
ssr: false, ssr: false,
pollInterval: 1000, pollInterval: 1000,
variables: { variables: {
name: get(match, 'params.instance') id: get(match, 'params.instance')
} }
}), }),
props: ({ data: { loading, error, variables, ...rest } }) => { props: ({ data: { loading, error, machine, ...rest } }) => {
let instance = find(get(rest, 'machines.results', []), [ if (machine) {
'name', const { ips } = machine;
variables.name
]);
if (instance) {
const { ips } = instance;
const grupedIps = ips const grupedIps = ips
.map(ip => ({ ip, openness: isPrivate(ip) ? 'private' : 'public' })) .map(ip => ({ ip, openness: isPrivate(ip) ? 'private' : 'public' }))
@ -164,11 +158,11 @@ export default compose(
{} {}
); );
instance = Object.assign({}, instance, { ips: grupedIps }); machine = Object.assign({}, machine, { ips: grupedIps });
} }
return { return {
instance, instance: machine,
loading, loading,
loadingError: error loadingError: error
}; };

View File

@ -152,14 +152,11 @@ export default compose(
ssr: false, ssr: false,
pollInterval: 1000, pollInterval: 1000,
variables: { variables: {
name: get(match, 'params.instance') id: get(match, 'params.instance')
} }
}), }),
props: ({ data: { loading, error, variables, refetch, ...rest } }) => { props: ({ data: { loading, error, machine, refetch, ...rest } }) => {
const { name } = variables; const tags = get(machine, 'tags', []).filter(
const instance = find(get(rest, 'machines.results', []), ['name', name]);
const tags = get(instance, 'tags', []).filter(
({ name = '' }) => !/^triton\.cns\./i.test(name) ({ name = '' }) => !/^triton\.cns\./i.test(name)
); );
@ -169,7 +166,7 @@ export default compose(
return { return {
tags, tags,
instance, instance: machine,
index, index,
loading, loading,
error, error,

View File

@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import { compose, graphql } from 'react-apollo'; import { compose, graphql } from 'react-apollo';
import { Margin } from 'styled-components-spacing'; import { Margin } from 'styled-components-spacing';
import find from 'lodash.find';
import get from 'lodash.get'; import get from 'lodash.get';
import { import {
@ -57,21 +56,19 @@ export default compose(
ssr: false, ssr: false,
variables: { variables: {
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
name: get(match, 'params.instance') id: get(match, 'params.instance')
} }
}), }),
props: ({ data }) => { props: ({ data }) => {
const { loading, error, variables, refetch, ...rest } = data; const { loading, error, machine } = data;
const { name } = variables;
const instance = find(get(rest, 'machines.results', []), ['name', name]); const metadata = get(machine, 'metadata', [])
const metadata = get(instance, 'metadata', [])
.filter(({ name = '' }) => name === 'user-script') .filter(({ name = '' }) => name === 'user-script')
.shift(); .shift();
return { return {
metadata, metadata,
instance, instance: machine,
loading, loading,
error error
}; };

View File

@ -103,7 +103,7 @@ exports[`renders <Breadcrumb /> without throwing 1`] = `
} }
.c0 { .c0 {
border-bottom: 1px solid rgb(216,216,216); border-bottom: 0.0625rem solid rgb(216,216,216);
} }
@media only screen and (min-width:48em) { @media only screen and (min-width:48em) {
@ -322,7 +322,7 @@ exports[`renders <Breadcrumb match /> without throwing 1`] = `
} }
.c0 { .c0 {
border-bottom: 1px solid rgb(216,216,216); border-bottom: 0.0625rem solid rgb(216,216,216);
} }
@media only screen and (min-width:48em) { @media only screen and (min-width:48em) {

View File

@ -4,13 +4,13 @@ import get from 'lodash.get';
import { Menu } from '@components/navigation'; import { Menu } from '@components/navigation';
export default connect((state, { match }) => { export default connect((state, { match }) => {
const instanceSlug = get(match, 'params.instance'); const instanceId = get(match, 'params.instance');
const allSections = get(state, 'ui.sections'); const allSections = get(state, 'ui.sections');
const sections = instanceSlug ? allSections.instances : []; const sections = instanceId ? allSections.instances : [];
const links = sections.map(({ name, pathname }) => ({ const links = sections.map(({ name, pathname }) => ({
name, name,
pathname: `/instances/${instanceSlug}/${pathname}` pathname: `/instances/${instanceId}/${pathname}`
})); }));
return { return {

View File

@ -1,25 +1,23 @@
query instance($name: String) { query instance($id: ID) {
machines(name: $name) { machine(id: $id) {
results { id
state
brand
name
created
updated
primary_ip
ips
docker
dns_names
compute_node
image {
id
name
}
package {
id id
state
brand
name name
created
updated
primary_ip
ips
docker
dns_names
compute_node
image {
id
name
}
package {
id
name
}
} }
} }
} }

View File

@ -1,17 +1,15 @@
query instance($name: String!) { query instance($id: ID!) {
machines(name: $name) { machine(id: $id) {
results { id
name
firewall_enabled
firewall_rules {
id id
name enabled
firewall_enabled rule_str
firewall_rules { rule_obj
id global
enabled description
rule_str
rule_obj
global
description
}
} }
} }
} }

View File

@ -1,24 +1,22 @@
query instance($name: String!) { query instance($id: ID!) {
machines(name: $name) { machine(id: $id) {
results { id
name
networks {
id id
name name
networks { public
fabric
description
subnet
provision_start_ip
provision_end_ip
gateway
resolvers
internet_nat
machines {
id id
name name
public
fabric
description
subnet
provision_start_ip
provision_end_ip
gateway
resolvers
internet_nat
machines {
id
name
}
} }
} }
} }

View File

@ -1,13 +1,11 @@
query instance($name: String!) { query metadata($id: ID!) {
machines(name: $name) { machine(id: $id) {
results { id
name
metadata {
id id
name name
metadata { value
id
name
value
}
} }
} }
} }

View File

@ -1,15 +1,13 @@
query instance($name: String!) { query instance($id: ID!) {
machines(name: $name) { machine(id: $id) {
results { id
name
snapshots {
id id
name name
snapshots { state
id created
name updated
state
created
updated
}
} }
} }
} }

View File

@ -1,13 +1,11 @@
query instance($name: String!) { query instance($id: ID!) {
machines(name: $name) { machine(id: $id) {
results { id
name
tags {
id id
name name
tags { value
id
name
value
}
} }
} }
} }

View File

@ -49,7 +49,7 @@ export default ({ theme }) => css`
} }
.CodeMirror { .CodeMirror {
border: solid 1px ${theme.grey}; border: solid ${remcalc(1)} ${theme.grey};
margin: ${remcalc(8)} 0 ${remcalc(8)} 0; margin: ${remcalc(8)} 0 ${remcalc(8)} 0;
font-family: "Roboto Mono", monospace !important; font-family: "Roboto Mono", monospace !important;
} }

View File

@ -103,7 +103,7 @@ exports[`Breadcrumb Default Breadcrumb 1`] = `
} }
.c0 { .c0 {
border-bottom: 1px solid rgb(216,216,216); border-bottom: 0.0625rem solid rgb(216,216,216);
} }
@media only screen and (min-width:48em) { @media only screen and (min-width:48em) {

View File

@ -2,11 +2,12 @@ import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { Row, Col } from 'joyent-react-styled-flexboxgrid'; import { Row, Col } from 'joyent-react-styled-flexboxgrid';
import { Padding } from 'styled-components-spacing'; import { Padding } from 'styled-components-spacing';
import remcalc from 'remcalc';
import Container from '../layout/view-container'; import Container from '../layout/view-container';
const BreadcrumContianer = styled(Container)` const BreadcrumContianer = styled(Container)`
border-bottom: 1px solid ${props => props.theme.grey}; border-bottom: ${remcalc(1)} solid ${props => props.theme.grey};
`; `;
/** /**

View File

@ -1,4 +1,5 @@
import styled from 'styled-components'; import styled from 'styled-components';
import remcalc from 'remcalc';
export default styled.span` export default styled.span`
display: inline-block; display: inline-block;
@ -15,6 +16,6 @@ export default styled.span`
& [data-ui-button='true']:not(:last-child) { & [data-ui-button='true']:not(:last-child) {
border-top-right-radius: 0; border-top-right-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
margin-right: -1px; margin-right: ${remcalc(-1)};
} }
`; `;

View File

@ -275,7 +275,7 @@ exports[`SectionList SectionList 1`] = `
list-style-type: none; list-style-type: none;
padding: 0.8125rem 0rem; padding: 0.8125rem 0rem;
margin: 1.125rem 0 0 0; margin: 1.125rem 0 0 0;
max-height: 50px; max-height: 3.125rem;
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
box-sizing: border-box; box-sizing: border-box;

View File

@ -9,7 +9,7 @@ const UnorderedList = styled.ul`
list-style-type: none; list-style-type: none;
padding: ${remcalc(13)} ${remcalc(0)}; padding: ${remcalc(13)} ${remcalc(0)};
margin: ${remcalc(18)} 0 0 0; margin: ${remcalc(18)} 0 0 0;
max-height: 50px; max-height: ${remcalc(50)};
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
box-sizing: border-box; box-sizing: border-box;

View File

@ -2517,9 +2517,9 @@ clone@^1.0.2:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f"
cloudapi-gql@^7.1.1: cloudapi-gql@^7.1.3:
version "7.1.2" version "7.1.3"
resolved "https://registry.yarnpkg.com/cloudapi-gql/-/cloudapi-gql-7.1.2.tgz#9087a60a5e95de259f62f2495744c526ec55a76c" resolved "https://registry.yarnpkg.com/cloudapi-gql/-/cloudapi-gql-7.1.3.tgz#bb963454dd68f6e36e2a44302456faecf97831aa"
dependencies: dependencies:
apr-map "3.x.x" apr-map "3.x.x"
boom "7.x.x" boom "7.x.x"