feat(my-joy-beta): initial tableview for networks and firewall

This commit is contained in:
Sérgio Ramos 2017-09-27 15:26:12 +01:00 committed by Sérgio Ramos
parent 7a2a61a9db
commit 09ef1cacde
6 changed files with 92 additions and 15 deletions

View File

@ -0,0 +1,22 @@
import React from 'react';
import forceArray from 'force-array';
import {
Card,
CardMeta,
CardTitle,
CardLabel,
CardView
} from 'joyent-ui-toolkit';
export default ({ rule = '', global = false, enabled = false, first, last }) => (
<Card collapsed flat={!last} topMargin={first} bottomless={!last} gapless>
<CardView>
<CardMeta>
<CardTitle>{rule}</CardTitle>
<CardLabel icon={global && String.fromCodePoint(0x1F30D)} />
<CardLabel color={enabled ? 'green' : 'red'} />
</CardMeta>
</CardView>
</Card>
);

View File

@ -1,3 +1,5 @@
export { default as Item } from './item'; export { default as Item } from './item';
export { default as List } from './list'; export { default as List } from './list';
export { default as KeyValue } from './key-value'; export { default as KeyValue } from './key-value';
export { default as Network } from './network';
export { default as FirewallRule } from './firewall-rule';

View File

@ -0,0 +1,23 @@
import React from 'react';
import forceArray from 'force-array';
import {
Card,
CardMeta,
CardTitle,
CardLabel,
CardView
} from 'joyent-ui-toolkit';
export default ({ name, gateway, subnet, resolvers = [], first, last }) => (
<Card collapsed flat={!last} topMargin={first} bottomless={!last} gapless>
<CardView>
<CardMeta>
<CardTitle>{name}</CardTitle>
<CardLabel>{gateway}</CardLabel>
<CardLabel>{subnet}</CardLabel>
<CardLabel>{forceArray(resolvers).join('\u00B7')}</CardLabel>
</CardMeta>
</CardView>
</Card>
);

View File

@ -9,6 +9,8 @@ import get from 'lodash.get';
import { ViewContainer, Title, StatusLoader, Message } from 'joyent-ui-toolkit'; import { ViewContainer, Title, StatusLoader, Message } from 'joyent-ui-toolkit';
import GetFirewallRules from '@graphql/list-firewall-rules.gql'; import GetFirewallRules from '@graphql/list-firewall-rules.gql';
import { FirewallRule as InstanceFirewallRule } from '@components/instances';
const Firewall = ({ const Firewall = ({
firewallEnabled = false, firewallEnabled = false,
@ -16,13 +18,20 @@ const Firewall = ({
loading, loading,
error error
}) => { }) => {
const values = forceArray(firewallRules);
const _title = <Title>Firewall</Title>; const _title = <Title>Firewall</Title>;
const _loading = !(loading && !forceArray(firewallRules).length) ? null : ( const _loading = !(loading && !values.length) ? null : (
<StatusLoader /> <StatusLoader />
); );
const _rules = !_loading && <ReactJson src={firewallRules} />; const _firewall = !_loading && values.map((rule, i, all) => (
const _enabled = !_loading && <ReactJson src={{ firewallEnabled }} />; <InstanceFirewallRule
key={rule.id}
{...rule}
last={all.length - 1 === i}
first={!i}
/>
));
const _error = !(error && !_loading) ? null : ( const _error = !(error && !_loading) ? null : (
<Message <Message
@ -37,8 +46,7 @@ const Firewall = ({
{_title} {_title}
{_loading} {_loading}
{_error} {_error}
{_enabled} {_firewall}
{_rules}
</ViewContainer> </ViewContainer>
); );
}; };

View File

@ -1,5 +1,4 @@
import React from 'react'; import React from 'react';
import ReactJson from 'react-json-view';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import forceArray from 'force-array'; import forceArray from 'force-array';
import { compose, graphql } from 'react-apollo'; import { compose, graphql } from 'react-apollo';
@ -9,14 +8,24 @@ import get from 'lodash.get';
import { ViewContainer, Title, StatusLoader, Message } from 'joyent-ui-toolkit'; import { ViewContainer, Title, StatusLoader, Message } from 'joyent-ui-toolkit';
import GetNetworks from '@graphql/list-networks.gql'; import GetNetworks from '@graphql/list-networks.gql';
import { Network as InstanceNetwork } from '@components/instances';
const Networks = ({ networks = [], loading, error }) => { const Networks = ({ networks = [], loading, error }) => {
const values = forceArray(networks);
const _title = <Title>Networks</Title>; const _title = <Title>Networks</Title>;
const _loading = !(loading && !forceArray(networks).length) ? null : ( const _loading = !(loading && !values.length) ? null : (
<StatusLoader /> <StatusLoader />
); );
const _summary = !_loading && <ReactJson src={networks} />; const _networks = !_loading && values.map((network, i, all) => (
<InstanceNetwork
key={network.id}
{...network}
last={all.length - 1 === i}
first={!i}
/>
));
const _error = !(error && !_loading) ? null : ( const _error = !(error && !_loading) ? null : (
<Message <Message
@ -31,7 +40,7 @@ const Networks = ({ networks = [], loading, error }) => {
{_title} {_title}
{_loading} {_loading}
{_error} {_error}
{_summary} {_networks}
</ViewContainer> </ViewContainer>
); );
}; };

View File

@ -2,6 +2,7 @@ import React from 'react';
import remcalc from 'remcalc'; import remcalc from 'remcalc';
import styled from 'styled-components'; import styled from 'styled-components';
import is, { isNot } from 'styled-is'; import is, { isNot } from 'styled-is';
import unitcalc from 'unitcalc';
const Dot = styled.span` const Dot = styled.span`
width: ${remcalc(6)}; width: ${remcalc(6)};
@ -9,7 +10,7 @@ const Dot = styled.span`
border-radius: ${remcalc(3)}; border-radius: ${remcalc(3)};
${is('hasChildren')` ${is('hasChildren')`
margin-right: ${remcalc(6)}; margin-left: ${remcalc(6)};
`}; `};
background-color: ${props => props.theme[props.color]}; background-color: ${props => props.theme[props.color]};
@ -18,6 +19,10 @@ const Dot = styled.span`
flex: none; flex: none;
`; `;
const Icon = styled.span`
background-color: none;
`;
const Label = styled.label` const Label = styled.label`
line-height: 1; line-height: 1;
padding: 0 ${remcalc(18)}; padding: 0 ${remcalc(18)};
@ -28,24 +33,31 @@ const Label = styled.label`
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: ${remcalc(100)}; min-width: ${remcalc(100)};
padding-left: 0;
${isNot('hasDot')` ${isNot('hasDot')`
width: ${remcalc(88)}; min-width: ${remcalc(88)};
`}; `};
${isNot('hasChildren')` ${isNot('hasChildren')`
width: ${remcalc(6)}; width: ${remcalc(6)};
min-width: ${remcalc(6)};
`}; `};
`; `;
const Span = styled.span` const Span = styled.span`
align-self: auto; align-self: auto;
flex: 1 1 auto; flex: 1 1 auto;
${is('hasDot')`
text-align: right;
`};
`; `;
export default ({ color, children, ...rest }) => { export default ({ color, icon, children, width, ...rest }) => {
const hasDot = Boolean(color); const hasIcon = Boolean(icon);
const hasDot = hasIcon || Boolean(color);
const hasChildren = Array.isArray(children) const hasChildren = Array.isArray(children)
? children.length ? children.length
@ -53,8 +65,9 @@ export default ({ color, children, ...rest }) => {
return ( return (
<Label {...rest} hasDot={hasDot} hasChildren={hasChildren}> <Label {...rest} hasDot={hasDot} hasChildren={hasChildren}>
{children && <Span hasDot={hasDot}>{children}</Span>}
{icon && <Icon>{icon}</Icon>}
{color && <Dot color={color} hasChildren={hasChildren} />} {color && <Dot color={color} hasChildren={hasChildren} />}
{children && <Span>{children}</Span>}
</Label> </Label>
); );
}; };