feat(my-joy-beta): create packages in create instance page

fixes #981
This commit is contained in:
Sara Vieira 2018-01-11 13:27:16 +00:00 committed by Sérgio Ramos
parent ed801eba0a
commit e12a0d4dd2
25 changed files with 4326 additions and 1088 deletions

36
packages/icons/src/cpu.js Normal file
View File

@ -0,0 +1,36 @@
import React from 'react';
import Colors from './colors';
import Rotate from './rotate';
import calcFill from './fill';
export default ({
fill = null,
light = false,
disabled = false,
direction = 'down',
style = {},
...rest
}) => (
<Colors white text grey>
{colors => (
<Rotate direction={direction}>
{({ style: rotateStyle }) => (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
style={{ ...style, ...rotateStyle }}
{...rest}
>
<path
fill={calcFill({ fill, disabled, light, colors })}
d="M20,18a2,2,0,0,1-2,2H6a2,2,0,0,1-2-2V6A2,2,0,0,1,6,4H18a2,2,0,0,1,2,2Zm3-5a1,1,0,0,0,0-2H22V10h1a1,1,0,0,0,0-2H22V6a4,4,0,0,0-4-4H16V1a1,1,0,0,0-2,0V2H13V1a1,1,0,0,0-2,0V2H10V1A1,1,0,0,0,8,1V2H6A4,4,0,0,0,2,6V8H1a1,1,0,0,0,0,2H2v1H1a1,1,0,0,0,0,2H2v1H1a1,1,0,0,0,0,2H2v2a4,4,0,0,0,4,4H8v1a1,1,0,0,0,2,0V22h1v1a1,1,0,0,0,2,0V22h1v1a1,1,0,0,0,2,0V22h2a4,4,0,0,0,4-4V16h1a1,1,0,0,0,0-2H22V13ZM7,7V17H17V7Zm9,9H8V8h8Z"
/>
</svg>
)}
</Rotate>
)}
</Colors>
);

View File

@ -0,0 +1,36 @@
import React from 'react';
import Colors from './colors';
import Rotate from './rotate';
import calcFill from './fill';
export default ({
fill = null,
light = false,
disabled = false,
direction = 'down',
style = {},
...rest
}) => (
<Colors white text grey>
{colors => (
<Rotate direction={direction}>
{({ style: rotateStyle }) => (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
style={{ ...style, ...rotateStyle }}
{...rest}
>
<path
fill={calcFill({ fill, disabled, light, colors })}
d="M18,17a1,1,0,0,1-1,1H3a1,1,0,0,1-1-1V3A1,1,0,0,1,3,2H17a1,1,0,0,1,1,1ZM17,0H3A3,3,0,0,0,0,3V17a3,3,0,0,0,3,3H17a3,3,0,0,0,3-3V3A3,3,0,0,0,17,0ZM10,15a5,5,0,1,1,5-5A5,5,0,0,1,10,15ZM10,4a6,6,0,1,0,6,6A6,6,0,0,0,10,4ZM9,10a1,1,0,1,0,1-1A1,1,0,0,0,9,10Z"
/>
</svg>
)}
</Rotate>
)}
</Colors>
);

View File

@ -36,3 +36,7 @@ export { default as User } from './user';
export { default as Randomize } from './randomize';
export { default as Name } from './name';
export { default as Fabric } from './fabric';
export { default as Cpu } from './cpu';
export { default as Memory } from './memory';
export { default as Storage } from './storage';
export { default as General } from './general';

View File

@ -0,0 +1,36 @@
import React from 'react';
import Colors from './colors';
import Rotate from './rotate';
import calcFill from './fill';
export default ({
fill = null,
light = false,
disabled = false,
direction = 'down',
style = {},
...rest
}) => (
<Colors white text grey>
{colors => (
<Rotate direction={direction}>
{({ style: rotateStyle }) => (
<svg
width="21.68"
height="21.68"
viewBox="0 0 21.68 21.68"
xmlns="http://www.w3.org/2000/svg"
style={{ ...style, ...rotateStyle }}
{...rest}
>
<path
fill={calcFill({ fill, disabled, light, colors })}
d="M6.24,11.9,8.36,14l1.42-1.41L7.66,10.49ZM4.12,14l2.12,2.12,1.42-1.41L5.54,12.6ZM8.36,9.78l2.13,2.12,1.41-1.41L9.78,8.36Zm2.13-2.12,2.12,2.12L14,8.36,11.9,6.24Zm2.12-2.13,2.12,2.13,1.41-1.42L14,4.12Zm8.48,0L16.14.59a2,2,0,0,0-2.83,0L.59,13.31a2,2,0,0,0,0,2.83l5,4.95a2,2,0,0,0,2.82,0l1.42-1.41.71.7A1,1,0,0,0,11.9,19l-.71-.71.71-.7.71.7A1,1,0,0,0,14,16.85l-.71-.71.71-.71.71.71a1,1,0,0,0,1.41-1.41L15.43,14l.71-.71.71.71a1,1,0,0,0,1.41-1.41l-.7-.71.7-.71.71.71a1,1,0,0,0,1.41-1.41l-.7-.71,1.41-1.42A2,2,0,0,0,21.09,5.54ZM7,19.68,2,14.73,14.73,2l4.95,5Z"
/>
</svg>
)}
</Rotate>
)}
</Colors>
);

View File

@ -0,0 +1,36 @@
import React from 'react';
import Colors from './colors';
import Rotate from './rotate';
import calcFill from './fill';
export default ({
fill = null,
light = false,
disabled = false,
direction = 'down',
style = {},
...rest
}) => (
<Colors white text grey>
{colors => (
<Rotate direction={direction}>
{({ style: rotateStyle }) => (
<svg
width="22"
height="22"
viewBox="0 0 22 22"
xmlns="http://www.w3.org/2000/svg"
style={{ ...style, ...rotateStyle }}
{...rest}
>
<path
fill={calcFill({ fill, disabled, light, colors })}
d="M17,16a1,1,0,1,1,1,1A1,1,0,0,1,17,16ZM7,17H8V15H7ZM5,17H6V15H5ZM3,17H4V15H3Zm14-7a1,1,0,1,1,1,1A1,1,0,0,1,17,10ZM7,11H8V9H7ZM5,11H6V9H5ZM3,11H4V9H3ZM19,4a1,1,0,1,1-1-1A1,1,0,0,1,19,4ZM7,5H8V3H7ZM5,5H6V3H5ZM3,5H4V3H3ZM22,2a2,2,0,0,0-2-2H2A2,2,0,0,0,0,2V6A1.91,1.91,0,0,0,.28,7,1.88,1.88,0,0,0,0,8v4a1.91,1.91,0,0,0,.28,1A1.88,1.88,0,0,0,0,14v4a2,2,0,0,0,2,2H20a2,2,0,0,0,2-2V14a1.88,1.88,0,0,0-.28-1A1.91,1.91,0,0,0,22,12V8a1.88,1.88,0,0,0-.28-1A1.91,1.91,0,0,0,22,6ZM20,18H2V14H20Zm0-6H2V8H20Zm0-6H2V2H20Z"
/>
</svg>
)}
</Rotate>
)}
</Colors>
);

View File

@ -23,9 +23,9 @@
"apollo": "^0.2.2",
"apr-intercept": "^1.0.4",
"clipboard-copy": "^1.2.0",
"constant-case": "^2.0.0",
"date-fns": "^1.29.0",
"declarative-redux-form": "^2.0.8",
"joyent-ui-toolkit": "^4.0.0",
"joyent-manifest-editor": "^1.4.0",
"joyent-ui-toolkit": "^4.0.1",
"lodash.find": "^4.6.0",
@ -35,6 +35,7 @@
"lunr": "^2.1.5",
"normalized-styled-components": "^1.0.17",
"param-case": "^2.1.1",
"prettysize": "^1.1.0",
"prop-types": "^15.6.0",
"react": "^16.2.0",
"react-apollo": "^1.4.16",

View File

@ -354,7 +354,15 @@ exports[`renders <Images expanded /> without throwing 1`] = `
<p
className="c1"
>
Hardware virtual machines are generally used for non-containerized applications. Infrastructure containers are generally for running any Linux image on secure, bare metal containers. Read the docs
Hardware virtual machines are generally used for non-containerized applications. Infrastructure containers are generally for running any Linux image on secure, bare metal containers.
<a
href="https://docs.joyent.com/private-cloud/images"
rel="noopener noreferrer"
target="_blank"
>
Read the docs
</a>
</p>
</div>
<div

View File

@ -0,0 +1,137 @@
import React from 'react';
import renderer from 'react-test-renderer';
import 'jest-styled-components';
import { Filters, Packages, Package, Overview } from '../package';
import Theme from '@mocks/theme';
it('renders <Overview hasVms/> without throwing', () => {
expect(
renderer
.create(
<Theme>
<Overview
name="test"
price="1"
memory="1"
vcpus="1"
hasVms
ssd
disk="1"
onCancel={() => {}}
/>
</Theme>
)
.toJSON()
).toMatchSnapshot();
});
it('renders <Overview /> without throwing', () => {
expect(
renderer
.create(
<Theme>
<Overview
name="test"
price="1"
memory="1"
vcpus="1"
disk="1"
onCancel={() => {}}
/>
</Theme>
)
.toJSON()
).toMatchSnapshot();
});
it('renders <Package /> without throwing', () => {
expect(
renderer
.create(
<Theme>
<Package
name="test"
price="1"
memory="1"
vcpus="1"
disk="1"
onCancel={() => {}}
/>
</Theme>
)
.toJSON()
).toMatchSnapshot();
});
it('renders <Filters /> without throwing', () => {
expect(
renderer
.create(
<Theme>
<Filters />
</Theme>
)
.toJSON()
).toMatchSnapshot();
});
it('renders <Packages expanded /> without throwing', () => {
expect(
renderer
.create(
<Theme>
<Packages expanded />
</Theme>
)
.toJSON()
).toMatchSnapshot();
});
it('renders <Packages pristine={false} /> without throwing', () => {
expect(
renderer
.create(
<Theme>
<Packages pristine={false} />
</Theme>
)
.toJSON()
).toMatchSnapshot();
});
it('renders <Packages packages=[{name: stuff, imageName: stuff}] /> without throwing', () => {
expect(
renderer
.create(
<Theme>
<Packages packages={[{ name: 'stuff', imageName: 'stuff' }]} />
</Theme>
)
.toJSON()
).toMatchSnapshot();
});
it('renders <Packages loading /> without throwing', () => {
expect(
renderer
.create(
<Theme>
<Packages loading />
</Theme>
)
.toJSON()
).toMatchSnapshot();
});
it('renders <Packages isVmSelected /> without throwing', () => {
expect(
renderer
.create(
<Theme>
<Packages isVmSelected />
</Theme>
)
.toJSON()
).toMatchSnapshot();
});

View File

@ -107,7 +107,14 @@ export default ({
<P>
Hardware virtual machines are generally used for non-containerized
applications. Infrastructure containers are generally for running
any Linux image on secure, bare metal containers. Read the docs
any Linux image on secure, bare metal containers.{' '}
<a
href="https://docs.joyent.com/private-cloud/images"
rel="noopener noreferrer"
target="_blank"
>
Read the docs
</a>
</P>
</Margin>
{loading ? (
@ -124,7 +131,7 @@ export default ({
</Margin>
<Row>
{images &&
images.map(image => (
images.filter(i => i.isVm === isVmSelected).map(image => (
<Col md={2} sm={3}>
<Card
selected={

View File

@ -0,0 +1,271 @@
import React, { Fragment } from 'react';
import { Field } from 'redux-form';
import styled from 'styled-components';
import { Margin } from 'styled-components-spacing';
import remcalc from 'remcalc';
import Flex from 'styled-flex-component';
import pretty from 'prettysize';
import {
H2,
H4,
FormGroup,
Button,
TableTh,
TableTr,
TableThead,
TableTbody,
Table,
TableTd,
Radio,
Checkbox,
Label,
GeneralIcon,
StorageIcon,
CpuIcon,
MemoryIcon
} from 'joyent-ui-toolkit';
const GroupIcons = {
MEMORY: <MemoryIcon fill="#32ABCF" />,
STORAGE: <StorageIcon fill="#A88A83" />,
GENERAL: <GeneralIcon fill="#E08A0E" />,
COMPUTE: <CpuIcon fill="#8043DC" />
};
const VerticalDivider = styled.div`
width: ${remcalc(1)};
background: ${props => props.theme.grey};
height: ${remcalc(18)};
display: flex;
align-self: flex-end;
margin: 0 ${remcalc(18)};
box-sizing: border-box;
`;
const Badge = styled.div`
background: ${props => props.theme.primary};
border-radius: ${remcalc(3)};
font-weight: 600;
line-height: normal;
font-size: ${remcalc(8)};
color: ${props => props.theme.white};
display: inline-flex;
align-items: center;
justify-content: center;
padding: ${remcalc(3)};
position: relative;
top: ${remcalc(-8)};
margin-left: ${remcalc(6)};
`;
export const Filters = () => (
<Margin top={4} bottom={3}>
<H4>Filters</H4>
<Flex alignCenter justifyBetween>
<FormGroup type="checkbox" name="compute-optimized" field={Field}>
<Checkbox>
<Label>
<Flex alignCenter>
{GroupIcons.COMPUTE}
<Margin right={1} left={1}>
Compute optimized
</Margin>
</Flex>
</Label>
</Checkbox>
</FormGroup>
<FormGroup type="checkbox" name="memory-optimized" field={Field}>
<Checkbox>
<Label>
<Flex alignCenter>
{GroupIcons.MEMORY}
<Margin left={1} right={2}>
Memory optimized
</Margin>
</Flex>
</Label>
</Checkbox>
</FormGroup>
<FormGroup type="checkbox" name="general-purpose" field={Field}>
<Checkbox>
<Label>
<Flex alignCenter>
{GroupIcons.GENERAL}
<Margin left={1} right={2}>
General Purpose
</Margin>
</Flex>
</Label>
</Checkbox>
</FormGroup>
<FormGroup type="checkbox" name="storage-optimized" field={Field}>
<Checkbox>
<Label>
<Flex alignCenter>
{GroupIcons.STORAGE}
<Margin left={1} right={2}>
Storage optimized
</Margin>
</Flex>
</Label>
</Checkbox>
</FormGroup>
<FormGroup type="checkbox" name="ssd" field={Field}>
<Checkbox>
<Label>SSD</Label>
</Checkbox>
</FormGroup>
</Flex>
</Margin>
);
export const Package = ({
selected = false,
id,
name,
group,
memory,
price,
vcpus,
disk,
ssd,
hasVms
}) => (
<TableTr>
<TableTd selected={selected}>
<FormGroup name="package" value={id} type="radio" field={Field} fluid>
<Radio noMargin>
<Flex alignCenter>
{GroupIcons[group]}
<Margin left={1} right={2}>
<Label>{name}</Label>
</Margin>
</Flex>
</Radio>
</FormGroup>
</TableTd>
<TableTd selected={selected}>{pretty(memory)}</TableTd>
<TableTd selected={selected}>
{pretty(disk)}
{ssd && <Badge>SSD</Badge>}
</TableTd>
{hasVms && <TableTd selected={selected}>{vcpus}</TableTd>}
<TableTd selected={selected}>{price}</TableTd>
</TableTr>
);
export const Packages = ({
handleSubmit,
pristine,
sortBy = 'name',
sortOrder = 'desc',
onSortBy = () => null,
hasVms,
children
}) => (
<form onSubmit={handleSubmit}>
<Table>
<TableThead>
<TableTr>
<TableTh
onClick={() => onSortBy('name', sortOrder)}
sortOrder={sortOrder}
showSort={sortBy === 'name'}
left
middle
xs="200"
actionable
>
<span>Name </span>
</TableTh>
<TableTh
xs="100"
onClick={() => onSortBy('ram', sortOrder)}
sortOrder={sortOrder}
showSort={sortBy === 'ram'}
left
middle
actionable
>
<span>RAM </span>
</TableTh>
<TableTh
xs="100"
onClick={() => onSortBy('disk', sortOrder)}
sortOrder={sortOrder}
showSort={sortBy === 'disk'}
left
middle
actionable
>
<span>Disk </span>
</TableTh>
{hasVms && (
<TableTh
xs="100"
onClick={() => onSortBy('vcpu', sortOrder)}
sortOrder={sortOrder}
showSort={sortBy === 'vcpu'}
left
middle
actionable
>
<span>vCPU</span>
</TableTh>
)}
<TableTh
xs="100"
onClick={() => onSortBy('price', sortOrder)}
sortOrder={sortOrder}
showSort={sortBy === 'price'}
left
middle
actionable
>
<span>$/hour</span>
</TableTh>
</TableTr>
</TableThead>
<TableTbody>{children}</TableTbody>
</Table>
<Button type="submit" disabled={pristine}>
Next
</Button>
</form>
);
export const Overview = ({
name,
price,
memory,
vcpus,
hasVms,
ssd,
disk,
onCancel
}) => (
<Fragment>
<Margin bottom={2} top={3}>
<H2>{name}</H2>
<Flex alignCenter>
<span>{price} $</span>
<VerticalDivider />
<span>{pretty(memory)}</span>
{hasVms && (
<Fragment>
<VerticalDivider />
<span>{vcpus} vCPUS</span>
</Fragment>
)}
<VerticalDivider />
<span>{pretty(disk)} disk</span>
<VerticalDivider />
{ssd && <span>SSD</span>}
</Flex>
</Margin>
<Button type="button" secondary onClick={onCancel}>
Edit
</Button>
</Fragment>
);

View File

@ -112,7 +112,6 @@ exports[`renders <InstanceList /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -230,6 +229,8 @@ exports[`renders <InstanceList /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c13:not(:first-child) {
@ -452,7 +453,11 @@ exports[`renders <InstanceList /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="bh"
onChange={[Function]}
/>
</li>
</div>
@ -651,7 +656,6 @@ exports[`renders <InstanceList allSelected /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -769,6 +773,8 @@ exports[`renders <InstanceList allSelected /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c13:not(:first-child) {
@ -991,7 +997,11 @@ exports[`renders <InstanceList allSelected /> without throwing 1`] = `
/>
</div>
<div
checked={true}
className="c12"
disabled={false}
id="bt"
onChange={[Function]}
/>
</li>
</div>
@ -1190,7 +1200,6 @@ exports[`renders <InstanceList sortBy /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -1289,66 +1298,6 @@ exports[`renders <InstanceList sortBy /> without throwing 1`] = `
border-right-width: 0;
}
.c13 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c13:not(:first-child) {
border-left-width: 0;
}
.c13:not(:last-child) {
border-right-width: 0;
}
.c14 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
width: 9.375rem;
display: table-cell;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c14:not(:first-child) {
border-left-width: 0;
}
.c14:not(:last-child) {
border-right-width: 0;
}
.c16 {
border-width: 0.0625rem;
border-style: solid;
@ -1435,6 +1384,68 @@ exports[`renders <InstanceList sortBy /> without throwing 1`] = `
border-right-width: 0;
}
.c13 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c13:not(:first-child) {
border-left-width: 0;
}
.c13:not(:last-child) {
border-right-width: 0;
}
.c14 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
width: 9.375rem;
display: table-cell;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c14:not(:first-child) {
border-left-width: 0;
}
.c14:not(:last-child) {
border-right-width: 0;
}
.c2 {
display: table-row;
color: rgba(73,73,73,1);
@ -1530,7 +1541,11 @@ exports[`renders <InstanceList sortBy /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="bk"
onChange={[Function]}
/>
</li>
</div>
@ -1729,7 +1744,6 @@ exports[`renders <InstanceList sortBy sortOrder /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -1828,66 +1842,6 @@ exports[`renders <InstanceList sortBy sortOrder /> without throwing 1`] = `
border-right-width: 0;
}
.c13 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c13:not(:first-child) {
border-left-width: 0;
}
.c13:not(:last-child) {
border-right-width: 0;
}
.c14 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
width: 9.375rem;
display: table-cell;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c14:not(:first-child) {
border-left-width: 0;
}
.c14:not(:last-child) {
border-right-width: 0;
}
.c16 {
border-width: 0.0625rem;
border-style: solid;
@ -1974,6 +1928,68 @@ exports[`renders <InstanceList sortBy sortOrder /> without throwing 1`] = `
border-right-width: 0;
}
.c13 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c13:not(:first-child) {
border-left-width: 0;
}
.c13:not(:last-child) {
border-right-width: 0;
}
.c14 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
width: 9.375rem;
display: table-cell;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c14:not(:first-child) {
border-left-width: 0;
}
.c14:not(:last-child) {
border-right-width: 0;
}
.c2 {
display: table-row;
color: rgba(73,73,73,1);
@ -2069,7 +2085,11 @@ exports[`renders <InstanceList sortBy sortOrder /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="bn"
onChange={[Function]}
/>
</li>
</div>
@ -2268,7 +2288,6 @@ exports[`renders <InstanceList submitting /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -2386,6 +2405,8 @@ exports[`renders <InstanceList submitting /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c13:not(:first-child) {
@ -2608,7 +2629,11 @@ exports[`renders <InstanceList submitting /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={true}
id="bq"
onChange={[Function]}
/>
</li>
</div>
@ -2807,7 +2832,6 @@ exports[`renders <InstanceList>{children}</InstanceList> without throwing 1`] =
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -2925,6 +2949,8 @@ exports[`renders <InstanceList>{children}</InstanceList> without throwing 1`] =
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c13:not(:first-child) {
@ -3147,7 +3173,11 @@ exports[`renders <InstanceList>{children}</InstanceList> without throwing 1`] =
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="bw"
onChange={[Function]}
/>
</li>
</div>
@ -3370,7 +3400,6 @@ exports[`renders <Item /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -3628,7 +3657,10 @@ exports[`renders <Item /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="Y"
/>
</li>
</div>
@ -3870,7 +3902,6 @@ exports[`renders <Item {...item} /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -4128,7 +4159,10 @@ exports[`renders <Item {...item} /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="be"
/>
</li>
</div>
@ -4372,7 +4406,6 @@ exports[`renders <Item allowedActions /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -4630,7 +4663,10 @@ exports[`renders <Item allowedActions /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="bc"
/>
</li>
</div>
@ -4914,7 +4950,6 @@ exports[`renders <Item mutating /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -5156,7 +5191,10 @@ exports[`renders <Item mutating /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="a"
/>
</li>
</div>

View File

@ -112,7 +112,6 @@ exports[`renders <Actions /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -230,6 +229,8 @@ exports[`renders <Actions /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c13:not(:first-child) {
@ -413,7 +414,11 @@ exports[`renders <Actions /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="bh"
onChange={[Function]}
/>
</li>
</div>
@ -616,7 +621,6 @@ exports[`renders <Item /> without throwing 1`] = `
}
.c10 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -817,7 +821,10 @@ exports[`renders <Item /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c10"
disabled={false}
id="Z"
/>
</li>
</div>
@ -1033,7 +1040,6 @@ exports[`renders <Item {...item} /> without throwing 1`] = `
}
.c10 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -1234,7 +1240,10 @@ exports[`renders <Item {...item} /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c10"
disabled={false}
id="bb"
/>
</li>
</div>
@ -1646,7 +1655,6 @@ exports[`renders <SnapshotList /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -1764,6 +1772,8 @@ exports[`renders <SnapshotList /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c13:not(:first-child) {
@ -1947,7 +1957,11 @@ exports[`renders <SnapshotList /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="be"
onChange={[Function]}
/>
</li>
</div>
@ -2145,7 +2159,6 @@ exports[`renders <SnapshotList allSelected /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -2263,6 +2276,8 @@ exports[`renders <SnapshotList allSelected /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c13:not(:first-child) {
@ -2446,7 +2461,11 @@ exports[`renders <SnapshotList allSelected /> without throwing 1`] = `
/>
</div>
<div
checked={true}
className="c12"
disabled={false}
id="bt"
onChange={[Function]}
/>
</li>
</div>
@ -2644,7 +2663,6 @@ exports[`renders <SnapshotList sortBy /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -2743,66 +2761,6 @@ exports[`renders <SnapshotList sortBy /> without throwing 1`] = `
border-right-width: 0;
}
.c13 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c13:not(:first-child) {
border-left-width: 0;
}
.c13:not(:last-child) {
border-right-width: 0;
}
.c14 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
width: 9.375rem;
display: table-cell;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c14:not(:first-child) {
border-left-width: 0;
}
.c14:not(:last-child) {
border-right-width: 0;
}
.c16 {
border-width: 0.0625rem;
border-style: solid;
@ -2858,6 +2816,68 @@ exports[`renders <SnapshotList sortBy /> without throwing 1`] = `
border-right-width: 0;
}
.c13 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c13:not(:first-child) {
border-left-width: 0;
}
.c13:not(:last-child) {
border-right-width: 0;
}
.c14 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
width: 9.375rem;
display: table-cell;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c14:not(:first-child) {
border-left-width: 0;
}
.c14:not(:last-child) {
border-right-width: 0;
}
.c2 {
display: table-row;
color: rgba(73,73,73,1);
@ -2945,7 +2965,11 @@ exports[`renders <SnapshotList sortBy /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="bk"
onChange={[Function]}
/>
</li>
</div>
@ -3143,7 +3167,6 @@ exports[`renders <SnapshotList sortBy sortOrder /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -3242,66 +3265,6 @@ exports[`renders <SnapshotList sortBy sortOrder /> without throwing 1`] = `
border-right-width: 0;
}
.c13 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c13:not(:first-child) {
border-left-width: 0;
}
.c13:not(:last-child) {
border-right-width: 0;
}
.c14 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
width: 9.375rem;
display: table-cell;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c14:not(:first-child) {
border-left-width: 0;
}
.c14:not(:last-child) {
border-right-width: 0;
}
.c16 {
border-width: 0.0625rem;
border-style: solid;
@ -3357,6 +3320,68 @@ exports[`renders <SnapshotList sortBy sortOrder /> without throwing 1`] = `
border-right-width: 0;
}
.c13 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
}
.c13:not(:first-child) {
border-left-width: 0;
}
.c13:not(:last-child) {
border-right-width: 0;
}
.c14 {
border-width: 0.0625rem;
border-style: solid;
border-color: rgb(216,216,216);
border-spacing: 0;
white-space: nowrap;
box-sizing: border-box;
padding: 0 1.5rem;
height: 3.75rem;
width: 9.375rem;
display: table-cell;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: middle;
text-align: left;
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c14:not(:first-child) {
border-left-width: 0;
}
.c14:not(:last-child) {
border-right-width: 0;
}
.c2 {
display: table-row;
color: rgba(73,73,73,1);
@ -3444,7 +3469,11 @@ exports[`renders <SnapshotList sortBy sortOrder /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={false}
id="bn"
onChange={[Function]}
/>
</li>
</div>
@ -3642,7 +3671,6 @@ exports[`renders <SnapshotList submitting /> without throwing 1`] = `
}
.c12 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -3760,6 +3788,8 @@ exports[`renders <SnapshotList submitting /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c13:not(:first-child) {
@ -3943,7 +3973,11 @@ exports[`renders <SnapshotList submitting /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c12"
disabled={true}
id="bq"
onChange={[Function]}
/>
</li>
</div>

View File

@ -7,6 +7,7 @@ import Name from '@containers/create-instance/name';
import Image from '@containers/create-instance/image';
import Metadata from '@containers/create-instance/metadata';
import Tags from '@containers/create-instance/tags';
import Package from '@containers/create-instance/package';
export default ({ step, ...props }) => (
<ViewContainer>
@ -19,6 +20,9 @@ export default ({ step, ...props }) => (
<Margin bottom={4}>
<Image {...props} expanded={step === 'image'} />
</Margin>
<Margin bottom={4}>
<Package {...props} expanded={step === 'package'} />
</Margin>
<Margin bottom={4}>
<Tags {...props} expanded={step === 'tags'} />
</Margin>

View File

@ -0,0 +1,204 @@
import React, { Fragment } from 'react';
import { Margin } from 'styled-components-spacing';
import { compose, graphql } from 'react-apollo';
import ReduxForm from 'declarative-redux-form';
import { connect } from 'react-redux';
import titleCase from 'title-case';
import get from 'lodash.get';
import { set } from 'react-redux-values';
import sortBy from 'lodash.sortby';
import find from 'lodash.find';
import constantCase from 'constant-case';
import { PackageIcon, StatusLoader, P } from 'joyent-ui-toolkit';
import {
Filters,
Packages,
Package,
Overview
} from '@components/create-instance/package';
import Title from '@components/create-instance/title';
import priceData from '../../data/prices.json';
import getPackages from '../../graphql/get-packages.gql';
const FORM_NAME = 'create-instance-package';
const PackageContainer = ({
expanded,
hasVms,
handleSubmit,
handleCancel,
loading,
packages,
selected = {},
sortOrder,
handleSortBy,
sortBy
}) => (
<Fragment>
<Title icon={<PackageIcon />}>Package</Title>
{expanded ? (
<Margin bottom={3}>
<P>
A package defines the specs of your instance. On Triton, packages can
only increase in size.{' '}
<a
href="https://docs.joyent.com/private-cloud/packages"
target="_blank"
rel="noopener noreferrer"
>
Read the docs
</a>
</P>
</Margin>
) : null}
{!loading && expanded ? (
<ReduxForm
form={`${FORM_NAME}-filters`}
destroyOnUnmount={false}
forceUnregisterOnUnmount={true}
>
{props => <Filters {...props} />}
</ReduxForm>
) : null}
{loading && expanded ? (
<StatusLoader />
) : (
<ReduxForm
form={FORM_NAME}
destroyOnUnmount={false}
forceUnregisterOnUnmount={true}
onSubmit={handleSubmit}
>
{props => (
<Fragment>
{expanded ? (
<Packages
{...props}
hasVms={hasVms}
sortBy={sortBy}
sortOrder={sortOrder}
onSortBy={handleSortBy}
>
{packages.map(({ id, ...pkg }) => (
<Package
key={id}
id={id}
selected={selected.id === id}
hasVms={hasVms}
{...pkg}
/>
))}
</Packages>
) : null}
{!expanded && selected.id ? (
<Overview {...selected} hasVms={hasVms} onCancel={handleCancel} />
) : null}
</Fragment>
)}
</ReduxForm>
)}
</Fragment>
);
export default compose(
graphql(getPackages, {
props: ({ data: { loading, packages = [] } }) => ({
loading,
packages: packages.map(pkg => {
const packagePrice = priceData.filter(p => p.name === pkg.name)[0];
const packageName = pkg.name.replace(/-kvm/g, '').trim();
return {
...pkg,
ssd: pkg.name.includes('fastdisk'),
vm: pkg.name.includes('kvm'),
memory: pkg.memory * 1000000,
disk: pkg.disk * 1000000,
price: packagePrice.cost || 0,
name: titleCase(packageName.replace(/-/g, ' ')),
group: constantCase(
pkg.group.replace(/optimized|purpose|KVM/gi, '').trim()
)
};
})
})
}),
connect(
({ form, values }, { packages, ...ownProps }) => {
const _sortBy = get(values, 'packages-list-sort-by', 'price');
const _sortOrder = get(values, 'packages-list-sort-order', 'asc');
const ssdOnly = get(form, `${FORM_NAME}-filters.values.ssd`, false);
const computeOptimized = get(
form,
`${FORM_NAME}-filters.values.compute-optimized`,
false
);
const generalPurpose = get(
form,
`${FORM_NAME}-filters.values.general-purpose`,
false
);
const storageOptimized = get(
form,
`${FORM_NAME}-filters.values.storage-optimized`,
false
);
const memoryOptimized = get(
form,
`${FORM_NAME}-filters.values.memory-optimized`,
false
);
const vmSelected = get(form, 'create-instance-image.values.vms', false);
const pkgSelected = get(form, `${FORM_NAME}.values.package`, null);
const sorted = sortBy(packages, [_sortBy]);
let filtered = sorted
.filter(p => (ssdOnly ? p.ssd === ssdOnly : true))
.filter(p => p.vm === vmSelected);
if (
computeOptimized ||
generalPurpose ||
storageOptimized ||
memoryOptimized
) {
filtered = filtered.filter(
p =>
(memoryOptimized && p.group === 'MEMORY') ||
(storageOptimized && p.group === 'STORAGE') ||
(generalPurpose && p.group === 'GENERAL') ||
(computeOptimized && p.group === 'COMPUTE')
);
}
return {
...ownProps,
sortBy: _sortBy,
sortOrder: _sortOrder,
packages: _sortOrder === 'asc' ? filtered : filtered.reverse(),
hasVms: vmSelected,
selected: find(packages, ['id', pkgSelected])
};
},
(dispatch, { history }) => ({
handleSubmit: () => history.push('/instances/~create/tags'),
handleCancel: () => history.push('/instances/~create/package'),
handleSortBy: (newSortBy, sortOrder) => {
dispatch([
set({
name: `packages-list-sort-order`,
value: sortOrder === 'desc' ? 'asc' : 'desc'
}),
set({
name: `packages-list-sort-by`,
value: newSortBy
})
]);
}
})
)
)(PackageContainer);

View File

@ -307,7 +307,6 @@ exports[`renders <List /> without throwing 1`] = `
}
.c25 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -532,6 +531,8 @@ exports[`renders <List /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c26:not(:first-child) {
@ -883,7 +884,11 @@ exports[`renders <List /> without throwing 1`] = `
/>
</div>
<div
checked={0}
className="c25"
disabled={false}
id="bc"
onChange={[Function]}
/>
</li>
</div>
@ -1319,7 +1324,6 @@ exports[`renders <List error /> without throwing 1`] = `
}
.c31 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -1575,6 +1579,8 @@ exports[`renders <List error /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c32:not(:first-child) {
@ -1966,7 +1972,11 @@ exports[`renders <List error /> without throwing 1`] = `
/>
</div>
<div
checked={0}
className="c31"
disabled={false}
id="bl"
onChange={[Function]}
/>
</li>
</div>
@ -2386,7 +2396,6 @@ exports[`renders <List instances /> without throwing 1`] = `
}
.c25 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -2629,6 +2638,8 @@ exports[`renders <List instances /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c26:not(:first-child) {
@ -3110,7 +3121,11 @@ exports[`renders <List instances /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="br"
onChange={[Function]}
/>
</li>
</div>
@ -3234,7 +3249,10 @@ exports[`renders <List instances /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="bt"
/>
</li>
</div>
@ -3383,7 +3401,10 @@ exports[`renders <List instances /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="bv"
/>
</li>
</div>
@ -4476,7 +4497,6 @@ exports[`renders <List instances selected /> without throwing 1`] = `
}
.c25 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -4719,6 +4739,8 @@ exports[`renders <List instances selected /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c26:not(:first-child) {
@ -5263,7 +5285,11 @@ exports[`renders <List instances selected /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="bB"
onChange={[Function]}
/>
</li>
</div>
@ -5387,7 +5413,10 @@ exports[`renders <List instances selected /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="bD"
/>
</li>
</div>
@ -5536,7 +5565,10 @@ exports[`renders <List instances selected /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="bF"
/>
</li>
</div>
@ -7109,7 +7141,6 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
}
.c25 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -7352,6 +7383,8 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c26:not(:first-child) {
@ -7896,7 +7929,11 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
/>
</div>
<div
checked={true}
className="c25"
disabled={false}
id="bL"
onChange={[Function]}
/>
</li>
</div>
@ -8020,7 +8057,10 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="bN"
/>
</li>
</div>
@ -8169,7 +8209,10 @@ exports[`renders <List instances selected=all /> without throwing 1`] = `
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="bP"
/>
</li>
</div>
@ -9951,7 +9994,6 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
}
.c25 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
}
@ -10194,6 +10236,8 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
height: 2.625rem;
color: rgb(189,189,189);
font-weight: 500;
color: rgba(73,73,73,1);
font-weight: bold;
}
.c26:not(:first-child) {
@ -10738,7 +10782,11 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
/>
</div>
<div
checked={true}
className="c25"
disabled={false}
id="bV"
onChange={[Function]}
/>
</li>
</div>
@ -10862,7 +10910,10 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="bX"
/>
</li>
</div>
@ -11011,7 +11062,10 @@ exports[`renders <List instances selected=all allowedActions /> without throwing
/>
</div>
<div
checked={false}
className="c25"
disabled={false}
id="bZ"
/>
</li>
</div>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
query Images {
packages {
id
name
memory
disk
vcpus
group
}
}

View File

@ -108,8 +108,8 @@ exports[`Form Checkbox 1`] = `
}
.c4 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
margin-bottom: 0.75rem;
}
.c0 {
@ -164,7 +164,10 @@ exports[`Form Checkbox 1`] = `
/>
</div>
<div
checked={false}
className="c4"
disabled={false}
id=""
>
<label
className="c5"
@ -482,8 +485,8 @@ exports[`Form Radio 1`] = `
}
.c4 {
margin-bottom: 0.75rem;
margin-left: 0.75rem;
margin-bottom: 0.75rem;
}
.c5 {
@ -517,16 +520,16 @@ exports[`Form Radio 1`] = `
<li
className="c0"
disabled={false}
>
<div
checked={false}
className="c1"
disabled={false}
id=""
type="radio"
>
<input
checked={false}
checked={undefined}
className="c2"
disabled={false}
id="c"
@ -539,6 +542,8 @@ exports[`Form Radio 1`] = `
</div>
<div
className="c4"
disabled={false}
id=""
>
<label
className="c5"

View File

@ -5,6 +5,7 @@ import { Input } from 'normalized-styled-components';
import remcalc from 'remcalc';
import is, { isNot } from 'styled-is';
import rndId from 'rnd-id';
import isUndefined from 'lodash.isundefined';
import BaseInput from './input';
@ -114,14 +115,18 @@ const InnerContainer = styled.div`
height: ${remcalc(18)};
position: relative;
cursor: pointer;
${isNot('noMargin')`
margin-bottom: ${remcalc(12)};
`};
`;
const Container = styled.div`
margin-bottom: ${remcalc(12)};
margin-left: ${remcalc(12)};
${isNot('noMargin')`
margin-bottom: ${remcalc(12)};
`};
`;
const ToggleBase = ({ container = null, type = 'radio' }) =>
@ -132,18 +137,28 @@ const ToggleBase = ({ container = null, type = 'radio' }) =>
[type]: true
};
const render = ({
const render = (
{
id, // ignore id from value
...oldValue
} = {}) => {
} = {}
) => {
const newValue = {
...oldValue,
id: rndId()
};
const checked =
['checkbox', 'radio'].indexOf(type) >= 0 &&
(rest.value === true || rest.checked === true);
const isValueUndefined = isUndefined(rest.value);
const isCheckedUndefined = isUndefined(rest.checked);
let checked;
if (type === 'checkbox' && (!isValueUndefined || !isCheckedUndefined)) {
checked = rest.value === true || rest.checked === true;
}
if (type === 'radio' && !isCheckedUndefined) {
checked = rest.checked === true;
}
const toggle = (
<InnerContainer {...types} type={type} {...rest}>
@ -164,9 +179,9 @@ const ToggleBase = ({ container = null, type = 'radio' }) =>
);
const el = OuterContainer ? (
<OuterContainer>
<OuterContainer {...rest}>
{toggle}
<Container>{children}</Container>
<Container {...rest}>{children}</Container>
</OuterContainer>
) : (
toggle

View File

@ -54,6 +54,5 @@ Radio.propTypes = {
};
Radio.defaultProps = {
checked: false,
disabled: false
};

View File

@ -38,9 +38,17 @@ import {
User as BaseUser,
Fabric as BaseFabric,
Name as BaseName,
Randomize as BaseRandomize
Randomize as BaseRandomize,
Cpu as BaseCpu,
Memory as BaseMemory,
Storage as BaseStorage,
General as BaseGeneral
} from 'joyent-icons';
export const General = Baseline(BaseGeneral);
export const Storage = Baseline(BaseStorage);
export const Cpu = Baseline(BaseCpu);
export const Memory = Baseline(BaseMemory);
export const Fabric = Baseline(BaseFabric);
export const Name = Baseline(BaseName);
export const Randomize = Baseline(BaseRandomize);

View File

@ -103,7 +103,11 @@ export {
Tags as TagsIcon,
Triton as TritonIcon,
User as UserIcon,
Name as NameIcon
Name as NameIcon,
General as GeneralIcon,
Storage as StorageIcon,
Cpu as CpuIcon,
Memory as MemoryIcon
} from './icons';
export {

View File

@ -2,7 +2,7 @@ import React from 'react';
import { Broadcast, Subscriber } from 'joy-react-broadcast';
import isBoolean from 'lodash.isboolean';
import styled, { css } from 'styled-components';
import is from 'styled-is';
import is, { isOr } from 'styled-is';
import remcalc from 'remcalc';
import Baseline from '../baseline';
@ -174,7 +174,7 @@ const BaseTh = styled.th`
color: ${props => props.theme.greyLight};
font-weight: 500;
${is('selected')`
${isOr('selected', 'showSort')`
color: ${props => props.theme.text};
font-weight: bold;
`};
@ -308,7 +308,7 @@ export const Tr = Baseline(({ children, ...rest }) => (
export const Th = Baseline(({ children, ...rest }) => (
<Propagate {...rest}>
{({ showSort, sortOrder, header, ...value }) => (
<BaseTh {...value} header={header} name="th">
<BaseTh {...value} showSort={showSort} header={header} name="th">
{children}
{!showSort || !header ? null : (
<ArrowIcon

View File

@ -2502,6 +2502,13 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
constant-case@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46"
dependencies:
snake-case "^2.1.0"
upper-case "^1.1.1"
constants-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
@ -8045,6 +8052,10 @@ pretty-format@^20.0.3:
ansi-regex "^2.1.1"
ansi-styles "^3.0.0"
prettysize@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/prettysize/-/prettysize-1.1.0.tgz#c6c52f87161ff172ea435f375f99831dd9a97bb0"
private@^0.1.6, private@^0.1.7, private@~0.1.5:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@ -9566,6 +9577,12 @@ smog-formula@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/smog-formula/-/smog-formula-1.0.2.tgz#25753f3bc7c0a7d10e0767a56e716ebd3bdd326e"
snake-case@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f"
dependencies:
no-case "^2.2.0"
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"