Add icons to service list and tidy up
This commit is contained in:
parent
9a1a84510f
commit
c06bbf4e31
@ -1,20 +1,33 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { MetricGraph, MetricView } from '@ui/components/metric';
|
import {
|
||||||
import PropTypes from '@root/prop-types';
|
MetricGraph,
|
||||||
|
MetricView,
|
||||||
|
MiniMetricMeta,
|
||||||
|
MiniMetricTitle,
|
||||||
|
MiniMetricSubtitle
|
||||||
|
} from '@ui/components/metric';
|
||||||
|
|
||||||
const MetricItem = ({
|
const MetricItem = ({
|
||||||
uuid,
|
uuid,
|
||||||
data
|
data
|
||||||
}) => (
|
}) => (
|
||||||
<MetricView borderless mini>
|
<MetricView borderless mini>
|
||||||
<MetricGraph data={data} />
|
<MiniMetricMeta>
|
||||||
|
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
|
||||||
|
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
|
||||||
|
</MiniMetricMeta>
|
||||||
|
<MetricGraph
|
||||||
|
data={data}
|
||||||
|
width={160}
|
||||||
|
height={72}
|
||||||
|
/>
|
||||||
</MetricView>
|
</MetricView>
|
||||||
);
|
);
|
||||||
|
|
||||||
MetricItem.propTypes = {
|
MetricItem.propTypes = {
|
||||||
uuid: React.PropTypes.string,
|
uuid: React.PropTypes.string,
|
||||||
data: PropTypes.data
|
data: React.PropTypes.data
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MetricItem;
|
export default MetricItem;
|
||||||
|
@ -5,6 +5,11 @@ import { Checkbox, FormGroup } from '@ui/components/form';
|
|||||||
import PropTypes from '@root/prop-types';
|
import PropTypes from '@root/prop-types';
|
||||||
import forceArray from 'force-array';
|
import forceArray from 'force-array';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
DataCentersIcon,
|
||||||
|
HealthyIcon,
|
||||||
|
InstancesMultipleIcon
|
||||||
|
} from '@ui/components/icons';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ListItem,
|
ListItem,
|
||||||
@ -15,7 +20,8 @@ import {
|
|||||||
ListItemDescription,
|
ListItemDescription,
|
||||||
ListItemGroupView,
|
ListItemGroupView,
|
||||||
ListItemOptions,
|
ListItemOptions,
|
||||||
ListItemHeader
|
ListItemHeader,
|
||||||
|
ListItemInfo
|
||||||
} from '@ui/components/list';
|
} from '@ui/components/list';
|
||||||
|
|
||||||
const StyledFormGroup = styled(FormGroup)`
|
const StyledFormGroup = styled(FormGroup)`
|
||||||
@ -36,7 +42,7 @@ const ServiceItem = ({
|
|||||||
service = {}
|
service = {}
|
||||||
}) => {
|
}) => {
|
||||||
const isChild = !!service.parent;
|
const isChild = !!service.parent;
|
||||||
|
console.log('service = ', service);
|
||||||
const childs = forceArray(service.services).map((service) => (
|
const childs = forceArray(service.services).map((service) => (
|
||||||
<ServiceItem
|
<ServiceItem
|
||||||
key={service.uuid}
|
key={service.uuid}
|
||||||
@ -69,10 +75,6 @@ const ServiceItem = ({
|
|||||||
<ListItemSubTitle>{service.instances} instances</ListItemSubTitle>
|
<ListItemSubTitle>{service.instances} instances</ListItemSubTitle>
|
||||||
);
|
);
|
||||||
|
|
||||||
const description = (
|
|
||||||
<ListItemDescription>Flags</ListItemDescription>
|
|
||||||
);
|
|
||||||
|
|
||||||
const onOptionsClick = (evt) => {
|
const onOptionsClick = (evt) => {
|
||||||
onQuickActions(evt, service.uuid);
|
onQuickActions(evt, service.uuid);
|
||||||
};
|
};
|
||||||
@ -81,12 +83,20 @@ const ServiceItem = ({
|
|||||||
<ListItemHeader>
|
<ListItemHeader>
|
||||||
<ListItemMeta>
|
<ListItemMeta>
|
||||||
{title}
|
{title}
|
||||||
{subtitle}
|
<ListItemDescription>
|
||||||
{description}
|
<ListItemInfo
|
||||||
|
icon={<InstancesMultipleIcon />}
|
||||||
|
iconPosition='top'
|
||||||
|
label={`${service.instances} ${service.instances > 1 ?
|
||||||
|
'instances' : 'instance' }`}
|
||||||
|
/>
|
||||||
|
<ListItemInfo
|
||||||
|
icon={<DataCentersIcon />}
|
||||||
|
label={service.datacenters[0].id}
|
||||||
|
/>
|
||||||
|
</ListItemDescription>
|
||||||
</ListItemMeta>
|
</ListItemMeta>
|
||||||
<ListItemOptions onClick={onOptionsClick}>
|
<ListItemOptions onClick={onOptionsClick} />
|
||||||
…
|
|
||||||
</ListItemOptions>
|
|
||||||
</ListItemHeader>
|
</ListItemHeader>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -99,7 +109,12 @@ const ServiceItem = ({
|
|||||||
<ListItemMeta>
|
<ListItemMeta>
|
||||||
{isChild && title}
|
{isChild && title}
|
||||||
{isChild && subtitle}
|
{isChild && subtitle}
|
||||||
{description}
|
<ListItemDescription>
|
||||||
|
<ListItemInfo
|
||||||
|
icon={<HealthyIcon />}
|
||||||
|
label='Healthy'
|
||||||
|
/>
|
||||||
|
</ListItemDescription>
|
||||||
</ListItemMeta>
|
</ListItemMeta>
|
||||||
<ItemMetricGroup
|
<ItemMetricGroup
|
||||||
datasets={service.metrics}
|
datasets={service.metrics}
|
||||||
|
@ -9,6 +9,7 @@ import moment from 'moment';
|
|||||||
|
|
||||||
const account = (state) => get(state, 'account.data', {});
|
const account = (state) => get(state, 'account.data', {});
|
||||||
const accountUi = (state) => get(state, 'account.ui', {});
|
const accountUi = (state) => get(state, 'account.ui', {});
|
||||||
|
const datacenters = (state) => get(state, 'datacenters.data', {});
|
||||||
const orgUiSections = (state) => get(state, 'orgs.ui.sections', []);
|
const orgUiSections = (state) => get(state, 'orgs.ui.sections', []);
|
||||||
const projectUiSections = (state) => get(state, 'projects.ui.sections', []);
|
const projectUiSections = (state) => get(state, 'projects.ui.sections', []);
|
||||||
const serviceUiTooltip = (state) => get(state, 'services.ui.tooltip', []);
|
const serviceUiTooltip = (state) => get(state, 'services.ui.tooltip', []);
|
||||||
@ -267,8 +268,9 @@ const datasets = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
const servicesByProjectId = (projectId, metricOptions) => createSelector(
|
const servicesByProjectId = (projectId, metricOptions) => createSelector(
|
||||||
[services, projectById(projectId), collapsedServices, metricsData, metricsUI],
|
[services, projectById(projectId), collapsedServices,
|
||||||
(services, project, collapsed, metrics, metricsUI) =>
|
instances, datacenters, metricsData, metricsUI],
|
||||||
|
(services, project, collapsed, instances, datacenters, metrics, metricsUI) =>
|
||||||
services.filter((s) => s.project === project.uuid)
|
services.filter((s) => s.project === project.uuid)
|
||||||
.map((service) => ({
|
.map((service) => ({
|
||||||
...service,
|
...service,
|
||||||
@ -278,6 +280,14 @@ const servicesByProjectId = (projectId, metricOptions) => createSelector(
|
|||||||
.map((service) => ({
|
.map((service) => ({
|
||||||
...service,
|
...service,
|
||||||
metrics: datasets(metrics, service.metrics, metricsUI, metricOptions),
|
metrics: datasets(metrics, service.metrics, metricsUI, metricOptions),
|
||||||
|
datacenters: instances.reduce((acc, instance) => {
|
||||||
|
if(instance.service === service.uuid) {
|
||||||
|
acc.push(instance);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, []).map((instance) =>
|
||||||
|
// TODO ensure uniqueness here
|
||||||
|
find(datacenters, ['uuid', instance.datacenter])),
|
||||||
collapsed: isCollapsed(collapsed, service.uuid),
|
collapsed: isCollapsed(collapsed, service.uuid),
|
||||||
services: service.services.map((service) => ({
|
services: service.services.map((service) => ({
|
||||||
...service,
|
...service,
|
||||||
|
@ -9,6 +9,7 @@ const style = css`
|
|||||||
|
|
||||||
${is('secondary')`
|
${is('secondary')`
|
||||||
color: ${colors.base.white};
|
color: ${colors.base.white};
|
||||||
|
text-decoration: none;
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
9
ui/src/components/icons/data-centers.js
Normal file
9
ui/src/components/icons/data-centers.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { Baseline } from '../../shared/composers';
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import DataCentersIcon from './svg/data-centers.svg';
|
||||||
|
|
||||||
|
export default Baseline(
|
||||||
|
DataCentersIcon
|
||||||
|
);
|
@ -1,4 +1,5 @@
|
|||||||
export { default as CloseIcon } from './close';
|
export { default as CloseIcon } from './close';
|
||||||
|
export { default as DataCentersIcon } from './data-centers';
|
||||||
export { default as HealthyIcon } from './healthy';
|
export { default as HealthyIcon } from './healthy';
|
||||||
export { default as HeartIcon } from './heart';
|
export { default as HeartIcon } from './heart';
|
||||||
export { default as InputConfirmIcon } from './input-confirm';
|
export { default as InputConfirmIcon } from './input-confirm';
|
||||||
|
@ -8,6 +8,7 @@ import ListItemOutlet from './outlet';
|
|||||||
import ListItemSubTitle from './subtitle';
|
import ListItemSubTitle from './subtitle';
|
||||||
import ListItemTitle from './title';
|
import ListItemTitle from './title';
|
||||||
import ListItemView from './view';
|
import ListItemView from './view';
|
||||||
|
import ListItemInfo from './info';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ListItemDescription,
|
ListItemDescription,
|
||||||
@ -19,5 +20,6 @@ export {
|
|||||||
ListItemOutlet,
|
ListItemOutlet,
|
||||||
ListItemSubTitle,
|
ListItemSubTitle,
|
||||||
ListItemTitle,
|
ListItemTitle,
|
||||||
ListItemView
|
ListItemView,
|
||||||
|
ListItemInfo
|
||||||
};
|
};
|
||||||
|
43
ui/src/components/list/info.js
Normal file
43
ui/src/components/list/info.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { unitcalc } from '../../shared/functions';
|
||||||
|
import { P } from '../base-elements';
|
||||||
|
|
||||||
|
const StyledContainer = styled.div`
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 ${unitcalc(2)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledIcon = styled.div`
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: ${unitcalc(1)};
|
||||||
|
vertical-align: ${props =>
|
||||||
|
props.iconPosition ?
|
||||||
|
props.iconPosition : 'text-top'};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledP = styled(P)`
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Info = ({
|
||||||
|
icon,
|
||||||
|
iconPosition,
|
||||||
|
label
|
||||||
|
}) => (
|
||||||
|
<StyledContainer>
|
||||||
|
<StyledIcon iconPosition={iconPosition}>
|
||||||
|
{icon}
|
||||||
|
</StyledIcon>
|
||||||
|
<StyledP>{label}</StyledP>
|
||||||
|
</StyledContainer>
|
||||||
|
);
|
||||||
|
|
||||||
|
Info.propTypes = {
|
||||||
|
icon: React.PropTypes.node,
|
||||||
|
iconPosition: React.PropTypes.string,
|
||||||
|
label: React.PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Info;
|
@ -12,11 +12,12 @@ const Nav = styled.nav`
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
${is('fromHeader')`
|
${is('fromHeader')`
|
||||||
border-left-color: ${colors.base.primary};
|
border-left-color: ${colors.base.primaryDesaturatedActive};
|
||||||
`};
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledButton = styled(Button)`
|
const StyledButton = styled(Button)`
|
||||||
|
position: relative;
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -46,8 +47,20 @@ const StyledButton = styled(Button)`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const StyledContainer = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledCircle = styled.div`
|
||||||
|
margin: 0 0 2px -2px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: ${colors.base.white};
|
||||||
|
width: 4px;
|
||||||
|
height: 4px;
|
||||||
|
`;
|
||||||
|
|
||||||
const Options = ({
|
const Options = ({
|
||||||
children,
|
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const render = ({
|
const render = ({
|
||||||
@ -61,7 +74,11 @@ const Options = ({
|
|||||||
rect
|
rect
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
<StyledContainer>
|
||||||
|
<StyledCircle />
|
||||||
|
<StyledCircle />
|
||||||
|
<StyledCircle />
|
||||||
|
</StyledContainer>
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
</Nav>
|
</Nav>
|
||||||
);
|
);
|
||||||
@ -74,7 +91,6 @@ const Options = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
Options.propTypes = {
|
Options.propTypes = {
|
||||||
children: React.PropTypes.node,
|
|
||||||
collapsed: React.PropTypes.bool,
|
collapsed: React.PropTypes.bool,
|
||||||
fromHeader: React.PropTypes.bool
|
fromHeader: React.PropTypes.bool
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Subscriber } from 'react-broadcast';
|
import { Subscriber } from 'react-broadcast';
|
||||||
import { is } from '../../shared/functions';
|
import { is, remcalc } from '../../shared/functions';
|
||||||
import { Baseline } from '../../shared/composers';
|
import { Baseline } from '../../shared/composers';
|
||||||
import Column from '../column';
|
import Column from '../column';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
@ -7,6 +7,9 @@ import React from 'react';
|
|||||||
|
|
||||||
const StyledColumn = styled(Column)`
|
const StyledColumn = styled(Column)`
|
||||||
display: block;
|
display: block;
|
||||||
|
min-width: auto;
|
||||||
|
max-width: ${remcalc(480)};
|
||||||
|
margin-left: auto;
|
||||||
|
|
||||||
${is('collapsed')`
|
${is('collapsed')`
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -5,6 +5,7 @@ import styled from 'styled-components';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const OuterBox = styled.div`
|
const OuterBox = styled.div`
|
||||||
|
box-sizing: border-box;
|
||||||
height: ${remcalc(53)};
|
height: ${remcalc(53)};
|
||||||
padding: ${remcalc(8)} ${remcalc(12)};
|
padding: ${remcalc(8)} ${remcalc(12)};
|
||||||
border-bottom: ${remcalc(1)} solid ${colors.seperator};
|
border-bottom: ${remcalc(1)} solid ${colors.seperator};
|
||||||
|
Loading…
Reference in New Issue
Block a user