feat(instances): responsive rules for package selection

This commit is contained in:
Fábio Moreira 2018-05-18 17:50:43 +01:00
parent 1424254290
commit 306dfb5b42
3 changed files with 229 additions and 54 deletions

View File

@ -14,13 +14,13 @@ import {
FormGroup, FormGroup,
Card, Card,
Button, Button,
TableTh, TableTh as BaseTableTh,
TableTr, TableTr,
TableThead, TableThead as BaseTableThead,
Divider, Divider,
TableTbody, TableTbody,
Table, Table,
TableTd, TableTd as BaseTableTd,
Radio, Radio,
Checkbox, Checkbox,
FormLabel, FormLabel,
@ -31,6 +31,7 @@ import {
} from 'joyent-ui-toolkit'; } from 'joyent-ui-toolkit';
import { NoPackages } from 'joyent-logo-assets'; import { NoPackages } from 'joyent-logo-assets';
import { breakpoints } from 'joyent-ui-toolkit/dist/es/breakpoints/screens';
const GroupIcons = { const GroupIcons = {
MEMORY: <MemoryIcon fill="#32ABCF" />, MEMORY: <MemoryIcon fill="#32ABCF" />,
@ -60,6 +61,67 @@ const FullWidthCard = styled(Card)`
`}; `};
`; `;
const TableThead = styled(BaseTableThead)`
${is('smallScreen')`
background-color: transparent;
`};
`;
const TableTh = styled(BaseTableTh)`
@media only screen and (min-width: ${remcalc(
breakpoints.medium.lower
)}) and (max-width: ${remcalc(700)}) {
&:not(:first-child) {
width: auto;
}
padding: 0 ${remcalc(3)};
}
${is('smallScreen')`
border: none;
color: #979797;
font-size: ${remcalc(13)};
height: auto;
padding: 0;
`};
`;
const TableTd = styled(BaseTableTd)`
@media only screen and (min-width: ${remcalc(
breakpoints.medium.lower
)}) and (max-width: ${remcalc(700)}) {
&:not(:first-child) {
width: auto;
}
padding: 0 ${remcalc(3)};
}
${is('smallScreen')`
border: none;
font-size: ${remcalc(15)};
height: auto;
padding: ${remcalc(4)} 0;
`};
`;
const FormItem = styled('form')`
border: 1px solid #d8d8d8;
border-radius: 4px;
${is('selected')`
border-color: #3B46CC;
background-color: rgba(59,70,204,0.05);
`};
`;
const PackageSpecs = styled('div')`
border-top: 1px solid #d8d8d8;
${is('selected')`
border-color: #3B46CC;
`};
`;
export const Filters = ({ onResetFilters }) => ( export const Filters = ({ onResetFilters }) => (
<Margin bottom={3}> <Margin bottom={3}>
<Margin bottom={3}> <Margin bottom={3}>
@ -142,48 +204,143 @@ export const Package = ({
ssd, ssd,
hasVms, hasVms,
sortBy, sortBy,
onRowClick onRowClick,
}) => ( xs
<TableTrActionable onClick={() => onRowClick(id)}> }) => {
<TableTd right selected={selected}> return xs ? (
<FormGroup name="package" value={id} type="radio" field={Field} fluid> <FormItem selected={selected}>
<Radio onBlur={null} noMargin> <Padding all={2} onClick={() => onRowClick(id)}>
<Flex alignCenter> <FormGroup name="package" value={id} type="radio" field={Field} fluid>
<Margin left={5} right={1}> <Radio onBlur={null} noMargin>
{GroupIcons[group]} <Flex alignCenter>
</Margin> <Margin left={2} right={1}>
<Margin left={1} right={2}> {GroupIcons[group]}
<FormLabel </Margin>
style={{ fontWeight: sortBy === 'name' ? 'bold' : 'normal' }} <Margin left={1} right={2}>
noMargin <FormLabel style={{ fontWeight: '600' }} noMargin actionable>
actionable {`${name} `}
> {ssd && <Sup badge>SSD</Sup>}
{name} </FormLabel>
</FormLabel> </Margin>
</Margin> </Flex>
</Flex> </Radio>
</Radio> </FormGroup>
</FormGroup> </Padding>
</TableTd> <PackageSpecs selected={selected}>
<TableTd right selected={selected} bold={sortBy === 'memory'}> <Padding top={1} left={2} bottom={1}>
{bytes(memory, { decimalPlaces: 0, unitSeparator: ' ' })} <Table>
</TableTd> <TableThead smallScreen>
<TableTd right selected={selected} bold={sortBy === 'disk'}> <TableTr>
<Margin inline right={1}> <TableTh left smallScreen>
{bytes(disk, { decimalPlaces: 0, unitSeparator: ' ' })} <Padding top={1}>
</Margin> <span>RAM </span>
{ssd && <Sup badge>SSD</Sup>} </Padding>
</TableTd> </TableTh>
{hasVms && ( <TableTh left smallScreen>
<TableTd right bold={sortBy === 'vcpus'} selected={selected}> <Padding top={1}>
{vcpus} <span>Disk </span>
</Padding>
</TableTh>
{hasVms && (
<TableTh left smallScreen>
<Padding top={1}>
<span>vCPU</span>
</Padding>
</TableTh>
)}
<TableTh left smallScreen>
<Padding top={1}>
<span>$/hour</span>
</Padding>
</TableTh>
</TableTr>
</TableThead>
<TableTbody>
<TableTrActionable onClick={() => onRowClick(id)}>
<TableTd
left
selected={selected}
bold={sortBy === 'memory'}
smallScreen
>
{bytes(memory, { decimalPlaces: 0, unitSeparator: ' ' })}
</TableTd>
<TableTd
left
selected={selected}
bold={sortBy === 'disk'}
smallScreen
>
<Margin inline right={1}>
{bytes(disk, { decimalPlaces: 0, unitSeparator: ' ' })}
</Margin>
</TableTd>
{hasVms && (
<TableTd
left
bold={sortBy === 'vcpus'}
selected={selected}
smallScreen
>
{vcpus}
</TableTd>
)}
<TableTd
left
bold={sortBy === 'price'}
selected={selected}
smallScreen
>
{fourDecimals(price)}
</TableTd>
</TableTrActionable>
</TableTbody>
</Table>
</Padding>
</PackageSpecs>
</FormItem>
) : (
<TableTrActionable onClick={() => onRowClick(id)}>
<TableTd right selected={selected}>
<FormGroup name="package" value={id} type="radio" field={Field} fluid>
<Radio onBlur={null} noMargin>
<Flex alignCenter>
<Margin left={5} right={1}>
{GroupIcons[group]}
</Margin>
<Margin left={1} right={2}>
<FormLabel
style={{ fontWeight: sortBy === 'name' ? 'bold' : 'normal' }}
noMargin
actionable
>
{name}
</FormLabel>
</Margin>
</Flex>
</Radio>
</FormGroup>
</TableTd> </TableTd>
)} <TableTd right selected={selected} bold={sortBy === 'memory'}>
<TableTd right bold={sortBy === 'price'} selected={selected}> {bytes(memory, { decimalPlaces: 0, unitSeparator: ' ' })}
{fourDecimals(price)} </TableTd>
</TableTd> <TableTd right selected={selected} bold={sortBy === 'disk'}>
</TableTrActionable> <Margin inline right={1}>
); {bytes(disk, { decimalPlaces: 0, unitSeparator: ' ' })}
</Margin>
{ssd && <Sup badge>SSD</Sup>}
</TableTd>
{hasVms && (
<TableTd right bold={sortBy === 'vcpus'} selected={selected}>
{vcpus}
</TableTd>
)}
<TableTd right bold={sortBy === 'price'} selected={selected}>
{fourDecimals(price)}
</TableTd>
</TableTrActionable>
);
};
export const Packages = ({ export const Packages = ({
pristine, pristine,

View File

@ -27,6 +27,9 @@ import { Filters, Packages, Package, Overview } from './components';
import getPackages from '../graphql/get-packages.gql'; import getPackages from '../graphql/get-packages.gql';
import priceData from './prices.json'; import priceData from './prices.json';
import { Forms, Values } from '../constants'; import { Forms, Values } from '../constants';
import { QueryBreakpoints } from 'joyent-ui-toolkit';
const { SmallOnly, Medium } = QueryBreakpoints;
const { IC_PKG_F_SELECT, IC_PKG_F_FILTER } = Forms; const { IC_PKG_F_SELECT, IC_PKG_F_FILTER } = Forms;
@ -84,14 +87,7 @@ const PackageComponent = ({
<StatusLoader /> <StatusLoader />
) : ( ) : (
<Fragment> <Fragment>
<Packages <SmallOnly>
{...props}
hasVms={hasVms}
sortBy={sortBy}
sortOrder={sortOrder}
onSortBy={handleSortBy}
packages={packages.length}
>
{packages.map(({ id, ...pkg }) => ( {packages.map(({ id, ...pkg }) => (
<Package <Package
key={id} key={id}
@ -100,10 +96,33 @@ const PackageComponent = ({
hasVms={hasVms} hasVms={hasVms}
onRowClick={handleRowClick} onRowClick={handleRowClick}
sortBy={sortBy} sortBy={sortBy}
xs
{...pkg} {...pkg}
/> />
))} ))}
</Packages> </SmallOnly>
<Medium>
<Packages
{...props}
hasVms={hasVms}
sortBy={sortBy}
sortOrder={sortOrder}
onSortBy={handleSortBy}
packages={packages.length}
>
{packages.map(({ id, ...pkg }) => (
<Package
key={id}
id={id}
selected={selected.id === id}
hasVms={hasVms}
onRowClick={handleRowClick}
sortBy={sortBy}
{...pkg}
/>
))}
</Packages>
</Medium>
<Margin top="4"> <Margin top="4">
<Button type="button" component={Link} to={next}> <Button type="button" component={Link} to={next}>
Next Next

View File

@ -45,7 +45,6 @@ const Label = styled.label`
height: ${remcalc(18)}; height: ${remcalc(18)};
box-sizing: border-box; box-sizing: border-box;
top: 0; top: 0;
right: 0;
cursor: pointer; cursor: pointer;
background-color: rgb(255, 255, 255); background-color: rgb(255, 255, 255);