2018-02-09 15:14:19 +02:00
|
|
|
import React from 'react';
|
2018-01-30 18:04:03 +02:00
|
|
|
import { Row, Col } from 'joyent-react-styled-flexboxgrid';
|
2017-12-21 02:12:42 +02:00
|
|
|
import styled, { withTheme } from 'styled-components';
|
2018-01-11 17:54:24 +02:00
|
|
|
import { Margin, Padding } from 'styled-components-spacing';
|
2017-12-21 02:12:42 +02:00
|
|
|
import remcalc from 'remcalc';
|
|
|
|
import titleCase from 'title-case';
|
|
|
|
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
|
|
|
|
|
|
|
|
import {
|
|
|
|
Card,
|
|
|
|
CardOutlet,
|
|
|
|
Divider,
|
|
|
|
ResetIcon,
|
|
|
|
Button,
|
|
|
|
H2,
|
|
|
|
Label,
|
|
|
|
QueryBreakpoints,
|
|
|
|
DotIcon,
|
|
|
|
DeleteIcon,
|
|
|
|
StartIcon,
|
|
|
|
StopIcon,
|
2018-02-06 13:23:50 +02:00
|
|
|
CopiableField
|
2017-12-21 02:12:42 +02:00
|
|
|
} from 'joyent-ui-toolkit';
|
|
|
|
|
|
|
|
const { SmallOnly, Medium } = QueryBreakpoints;
|
|
|
|
|
|
|
|
const stateColor = {
|
|
|
|
PROVISIONING: 'primary',
|
|
|
|
RUNNING: 'green',
|
|
|
|
STOPPING: 'grey',
|
|
|
|
STOPPED: 'grey',
|
|
|
|
DELETED: 'secondaryActive',
|
|
|
|
FAILED: 'red'
|
|
|
|
};
|
|
|
|
|
|
|
|
const GreyLabel = styled(Label)`
|
|
|
|
opacity: 0.5;
|
|
|
|
padding-right: ${remcalc(3)};
|
|
|
|
`;
|
|
|
|
|
|
|
|
const Flex = styled.div`
|
|
|
|
align-items: center;
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
|
|
|
@media (max-width: ${remcalc(767)}) {
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
const VerticalDivider = styled.div`
|
|
|
|
width: ${remcalc(1)};
|
|
|
|
background: ${props => props.theme.grey};
|
|
|
|
height: ${remcalc(24)};
|
|
|
|
display: flex;
|
|
|
|
align-self: flex-end;
|
|
|
|
margin: 0 ${remcalc(18)};
|
|
|
|
|
|
|
|
@media (max-width: ${remcalc(767)}) {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
export const Meta = ({
|
|
|
|
created,
|
|
|
|
updated,
|
|
|
|
state,
|
|
|
|
brand,
|
|
|
|
image,
|
|
|
|
...instance
|
|
|
|
}) => [
|
|
|
|
<Row middle="xs">
|
|
|
|
<Col xs={12}>
|
|
|
|
<H2>{(instance.package || {}).name}</H2>
|
|
|
|
</Col>
|
|
|
|
</Row>,
|
|
|
|
<Margin top={2} bottom={3}>
|
|
|
|
<Flex>
|
2018-01-04 13:22:32 +02:00
|
|
|
<Label>
|
|
|
|
{image && image.name ? titleCase(image.name) : 'Custom Image'}
|
|
|
|
</Label>
|
2017-12-21 02:12:42 +02:00
|
|
|
<VerticalDivider />
|
|
|
|
<Label>
|
|
|
|
{brand === 'LX'
|
|
|
|
? 'Infrastructure Container'
|
|
|
|
: 'Hardware Virtual Machine'}
|
|
|
|
</Label>
|
|
|
|
<VerticalDivider />
|
|
|
|
<Flex>
|
|
|
|
<DotIcon
|
|
|
|
marginRight={remcalc(6)}
|
2018-02-01 12:38:12 +02:00
|
|
|
size={remcalc(15)}
|
2017-12-21 02:12:42 +02:00
|
|
|
color={stateColor[state]}
|
|
|
|
/>
|
|
|
|
{titleCase(state)}
|
|
|
|
</Flex>
|
|
|
|
</Flex>
|
|
|
|
<Margin top={1}>
|
|
|
|
<Flex>
|
|
|
|
<Flex>
|
|
|
|
<GreyLabel>Created: </GreyLabel>
|
|
|
|
<Label> {distanceInWordsToNow(created)} ago</Label>
|
|
|
|
</Flex>
|
|
|
|
<VerticalDivider />
|
|
|
|
<Flex>
|
|
|
|
<GreyLabel>Updated: </GreyLabel>
|
|
|
|
<Label> {distanceInWordsToNow(updated)} ago</Label>
|
|
|
|
</Flex>
|
|
|
|
</Flex>
|
|
|
|
</Margin>
|
|
|
|
</Margin>
|
|
|
|
];
|
|
|
|
|
|
|
|
export default withTheme(
|
|
|
|
({
|
|
|
|
instance = {},
|
|
|
|
starting = false,
|
|
|
|
stopping = false,
|
|
|
|
rebooting = false,
|
2018-01-04 13:05:22 +02:00
|
|
|
removing = false,
|
2017-12-21 02:12:42 +02:00
|
|
|
onAction,
|
|
|
|
theme = {}
|
|
|
|
}) => (
|
|
|
|
<Row>
|
|
|
|
<Col xs={12} sm={12} md={9}>
|
|
|
|
<Card>
|
2018-01-11 17:54:24 +02:00
|
|
|
<CardOutlet>
|
|
|
|
<Padding all={4}>
|
|
|
|
<Meta {...instance} />
|
|
|
|
<Row between="xs">
|
|
|
|
<Col xs={9}>
|
|
|
|
<SmallOnly>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
loading={starting}
|
|
|
|
disabled={instance.state !== 'STOPPED'}
|
|
|
|
onClick={() => onAction('start')}
|
|
|
|
secondary
|
|
|
|
small
|
|
|
|
icon
|
|
|
|
>
|
|
|
|
<StartIcon disabled={instance.state !== 'STOPPED'} />
|
|
|
|
</Button>
|
|
|
|
</SmallOnly>
|
|
|
|
<Medium>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
loading={starting}
|
|
|
|
disabled={instance.state !== 'STOPPED'}
|
|
|
|
onClick={() => onAction('start')}
|
|
|
|
secondary
|
|
|
|
bold
|
|
|
|
icon
|
|
|
|
>
|
|
|
|
<StartIcon disabled={instance.state !== 'STOPPED'} />
|
|
|
|
<span>Start</span>
|
|
|
|
</Button>
|
|
|
|
</Medium>
|
|
|
|
<SmallOnly>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
loading={stopping}
|
|
|
|
disabled={instance.state !== 'RUNNING'}
|
|
|
|
onClick={() => onAction('stop')}
|
|
|
|
secondary
|
|
|
|
small
|
|
|
|
icon
|
|
|
|
>
|
|
|
|
<StopIcon disabled={instance.state !== 'RUNNING'} />
|
|
|
|
</Button>
|
|
|
|
</SmallOnly>
|
|
|
|
<Medium>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
loading={stopping}
|
|
|
|
disabled={instance.state !== 'RUNNING'}
|
|
|
|
onClick={() => onAction('stop')}
|
|
|
|
secondary
|
|
|
|
bold
|
|
|
|
icon
|
|
|
|
>
|
|
|
|
<StopIcon disabled={instance.state !== 'RUNNING'} />
|
|
|
|
<span>Stop</span>
|
|
|
|
</Button>
|
|
|
|
</Medium>
|
|
|
|
<SmallOnly>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
loading={rebooting}
|
|
|
|
disabled={instance.state !== 'RUNNING'}
|
|
|
|
onClick={() => onAction('reboot')}
|
|
|
|
secondary
|
|
|
|
small
|
|
|
|
icon
|
|
|
|
>
|
|
|
|
<ResetIcon disabled={instance.state !== 'RUNNING'} />
|
|
|
|
</Button>
|
|
|
|
</SmallOnly>
|
|
|
|
<Medium>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
loading={rebooting}
|
|
|
|
disabled={instance.state !== 'RUNNING'}
|
|
|
|
onClick={() => onAction('reboot')}
|
|
|
|
secondary
|
|
|
|
bold
|
|
|
|
icon
|
|
|
|
>
|
|
|
|
<ResetIcon disabled={instance.state !== 'RUNNING'} />
|
|
|
|
<span>Reboot</span>
|
|
|
|
</Button>
|
|
|
|
</Medium>
|
|
|
|
</Col>
|
|
|
|
<Col xs={3}>
|
|
|
|
<SmallOnly>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
loading={removing}
|
2018-01-04 13:05:22 +02:00
|
|
|
disabled={
|
|
|
|
['RUNNING', 'STOPPED'].indexOf(instance.state) < 0
|
|
|
|
}
|
2018-01-11 17:54:24 +02:00
|
|
|
onClick={() => onAction('remove')}
|
|
|
|
secondary
|
|
|
|
small
|
|
|
|
right
|
|
|
|
icon
|
|
|
|
error
|
|
|
|
>
|
|
|
|
<DeleteIcon
|
|
|
|
fill={theme.red}
|
|
|
|
disabled={
|
|
|
|
['RUNNING', 'STOPPED'].indexOf(instance.state) < 0
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
</Button>
|
|
|
|
</SmallOnly>
|
|
|
|
<Medium>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
loading={removing}
|
2018-01-04 13:05:22 +02:00
|
|
|
disabled={
|
|
|
|
['RUNNING', 'STOPPED'].indexOf(instance.state) < 0
|
|
|
|
}
|
2018-01-11 17:54:24 +02:00
|
|
|
onClick={() => onAction('remove')}
|
|
|
|
secondary
|
|
|
|
bold
|
|
|
|
right
|
|
|
|
icon
|
|
|
|
error
|
|
|
|
>
|
|
|
|
<DeleteIcon
|
|
|
|
fill={
|
|
|
|
['RUNNING', 'STOPPED'].indexOf(instance.state) >= 0
|
|
|
|
? theme.red
|
|
|
|
: undefined
|
|
|
|
}
|
|
|
|
disabled={
|
|
|
|
['RUNNING', 'STOPPED'].indexOf(instance.state) < 0
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
<span>Remove</span>
|
|
|
|
</Button>
|
|
|
|
</Medium>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
<Margin bottom={5} top={4}>
|
|
|
|
<Divider height={remcalc(1)} />
|
|
|
|
</Margin>
|
|
|
|
<CopiableField
|
|
|
|
text={(instance.id || '').split('-')[0]}
|
|
|
|
label="Short ID"
|
|
|
|
/>
|
|
|
|
<CopiableField text={instance.id} label="ID" />
|
|
|
|
<CopiableField text={instance.compute_node} label="CN UUID" />
|
|
|
|
{instance.image &&
|
|
|
|
instance.image.id && (
|
|
|
|
<CopiableField text={instance.image.id} label="Image UUID" />
|
|
|
|
)}
|
2017-12-21 02:12:42 +02:00
|
|
|
<CopiableField
|
2018-01-11 17:54:24 +02:00
|
|
|
text={`ssh root@${instance.primary_ip}`}
|
|
|
|
label="Login"
|
2017-12-21 02:12:42 +02:00
|
|
|
/>
|
2018-01-11 17:54:24 +02:00
|
|
|
{(instance.ips || []).map((ip, i) => (
|
|
|
|
<CopiableField
|
|
|
|
key={i}
|
|
|
|
noMargin={i === instance.ips.length - 1}
|
|
|
|
text={ip}
|
|
|
|
label={`IP address ${i + 1}`}
|
|
|
|
/>
|
|
|
|
))}
|
|
|
|
</Padding>
|
2017-12-21 02:12:42 +02:00
|
|
|
</CardOutlet>
|
|
|
|
</Card>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
)
|
|
|
|
);
|