diff --git a/frontend/locales/en-us.json b/frontend/locales/en-us.json
index b034feb0..80aafe5c 100644
--- a/frontend/locales/en-us.json
+++ b/frontend/locales/en-us.json
@@ -2,18 +2,18 @@
"your-dashboard": "Your dashboard",
"project-feed": "Project Feed",
"summary": "Summary",
- "metric-s": "Metrics",
+ "metrics": "Metrics",
"networks": "Networks",
"tags-metadata": "Tags and Meta Data",
"activity-feed": "Activity Feed",
"firewall": "Firewall",
+ "service-manifest": "Service manifest",
"settings": "Settings",
"projects": "Projects",
"people": "People",
"services": "Services",
"instances": "Instances",
"manifest": "Project manifest",
- "service-manifest": "Service manifest",
"create-new": "Create new project",
"rollback": "Rollback",
"import-services-title": "Import your services",
@@ -52,7 +52,7 @@
"description": "Please provide your billing details.",
"save-details-label": "Save details"
},
- "metrics": {
+ "metrics-section": {
"add": {
"add-label": "Add",
"added-label": "Added",
diff --git a/frontend/src/components/metric-charts/add-metrics.js b/frontend/src/components/metric-charts/add-metrics.js
index 702d3983..eb5d05f7 100644
--- a/frontend/src/components/metric-charts/add-metrics.js
+++ b/frontend/src/components/metric-charts/add-metrics.js
@@ -21,26 +21,29 @@ const AddMetrics = ({
const addButton = (metric) => (
-
+
);
const addedButton = (
-
+
);
const metricList = metricTypes.map((metric) => (
-
+
-
+
-
+
{ added(metric.uuid) ? addedButton : addButton(metric.uuid) }
diff --git a/frontend/src/components/metric-charts/index.js b/frontend/src/components/metric-charts/index.js
index 9808002b..fb132168 100644
--- a/frontend/src/components/metric-charts/index.js
+++ b/frontend/src/components/metric-charts/index.js
@@ -47,13 +47,13 @@ const MetricCharts = ({
{type.name}
- {/**/}
+ {/**/}
{optionList}
-
+
diff --git a/frontend/src/containers/services/topology.js b/frontend/src/containers/services/topology.js
index 1723f6bd..37472f96 100644
--- a/frontend/src/containers/services/topology.js
+++ b/frontend/src/containers/services/topology.js
@@ -2,7 +2,8 @@ import React from 'react';
import { connect } from 'react-redux';
import styled from 'styled-components';
import PropTypes from '@root/prop-types';
-import { colors } from '@ui/shared/constants';
+import { colors, breakpoints } from '@ui/shared/constants';
+import { unitcalc } from '@ui/shared/functions';
import { TopologyGraph } from '@ui/components/topology';
import { LayoutContainer } from '@components/layout';
import ServicesTooltip from '@components/services/tooltip';
@@ -22,6 +23,11 @@ const StyledBackground = styled.div`
const StyledContainer = styled(LayoutContainer)`
position: relative;
+ padding: ${unitcalc(4)} 2rem;
+
+ ${breakpoints.large`
+ padding: ${unitcalc(4)} 0;
+ `}
`;
const Services = (props) => {
@@ -30,14 +36,16 @@ const Services = (props) => {
org = {},
project = {},
toggleTooltip,
- uiTooltip
+ uiTooltip,
+ push
} = props;
- const onQuickActions = (evt, tooltipData) => {
- const service = services.reduce((acc, service) =>
- service.uuid === tooltipData.service ? service : acc
- , {});
+ const getService = (uuid) => services.reduce((acc, service) =>
+ service.uuid === uuid ? service : acc
+ , {});
+ const onQuickActions = (evt, tooltipData) => {
+ const service = getService(tooltipData.service);
const ttData = {
...tooltipData,
data: {
@@ -54,11 +62,20 @@ const Services = (props) => {
service: uiTooltip.service
});
+ const onNodeTitleClick = (uuid) => {
+ const service = getService(uuid);
+
+ const path = `/${org.id}/projects/${project.id}/services/${service.id}`;
+
+ push(path);
+ };
+
return (
@@ -71,6 +88,7 @@ Services.propTypes = {
org: PropTypes.org,
services: React.PropTypes.arrayOf(PropTypes.service),
project: PropTypes.project,
+ push: React.PropTypes.func.isRequired,
toggleTooltip: React.PropTypes.func,
uiTooltip: React.PropTypes.object
};
@@ -78,12 +96,14 @@ Services.propTypes = {
const mapStateToProps = (state, {
match = {
params: {}
- }
+ },
+ push
}) => ({
org: orgByIdSelector(match.params.org)(state),
project: projectByIdSelector(match.params.projectId)(state),
services: servicesForTopologySelector(match.params.projectId)(state),
- uiTooltip: serviceUiTooltipSelector(state)
+ uiTooltip: serviceUiTooltipSelector(state),
+ push: push
});
const mapDispatchToProps = (dispatch) => ({
diff --git a/frontend/src/mock-state.json b/frontend/src/mock-state.json
index 2551e698..d9276147 100644
--- a/frontend/src/mock-state.json
+++ b/frontend/src/mock-state.json
@@ -75,7 +75,7 @@
"id": "cpu-wait-time",
"min": 0,
"max": 100,
- "measurement": "%"
+ "measurement": "bytes"
}, {
"uuid": "dca08514-72e5-46ce-ad91-e68b3b0914d7",
"name": "Zfs used",
@@ -96,14 +96,14 @@
"id": "load-average",
"min": 0,
"max": 20,
- "measurement": "kb"
+ "measurement": " Mb"
}, {
"uuid": "dca08514-72e5-46ce-ad92-e68b3b0914d4",
"name": "Memory",
"id": "mem-agg-usage",
"min": 0,
"max": 100,
- "measurement": "%"
+ "measurement": " Mb"
}, {
"uuid": "dca08514-72e5-46ce-ad93-e68b3b0914d4",
"name": "Memory limit",
diff --git a/ui/src/components/topology/graph-node/index.js b/ui/src/components/topology/graph-node/index.js
index eabaa865..ed2061cd 100644
--- a/ui/src/components/topology/graph-node/index.js
+++ b/ui/src/components/topology/graph-node/index.js
@@ -14,6 +14,7 @@ const GraphNode = ({
data,
index,
onDragStart,
+ onNodeTitleClick,
onQuickActions
}) => {
@@ -61,6 +62,9 @@ const GraphNode = ({
onQuickActions(evt, d);
};
+ const onTitleClick = () =>
+ onNodeTitleClick(data.uuid);
+
const onStart = (evt) => {
evt.preventDefault();
onDragStart(evt, data.id);
@@ -107,6 +111,7 @@ const GraphNode = ({
{
return (
@@ -15,6 +16,8 @@ const GraphNodeTitle = ({
x={Constants.paddingLeft}
y={30}
connected={connected}
+ onClick={onNodeTitleClick}
+ onKeyDown={onNodeTitleClick}
>
{data.name}
@@ -32,7 +35,8 @@ const GraphNodeTitle = ({
GraphNodeTitle.propTypes = {
connected: React.PropTypes.bool,
- data: React.PropTypes.object.isRequired
+ data: React.PropTypes.object.isRequired,
+ onNodeTitleClick: React.PropTypes.func
};
export default Baseline(
diff --git a/ui/src/components/topology/topology-graph.js b/ui/src/components/topology/topology-graph.js
index ef30e8df..870aea5c 100644
--- a/ui/src/components/topology/topology-graph.js
+++ b/ui/src/components/topology/topology-graph.js
@@ -5,7 +5,6 @@ import Constants from './constants';
import GraphNode from './graph-node';
import GraphLink from './graph-link';
import React from 'react';
-import { triggerMouseEvent } from '../../shared/functions';
const StyledSvg = styled.svg`
width: 100%;
@@ -103,26 +102,36 @@ class TopologyGraph extends React.Component {
}
}
- isWithinSVGBounds(target, x, y) {
- const svgBounds = document
- .getElementsByClassName('topology-svg')[0]
- .getBoundingClientRect();
+ getSvgSize() {
+ return document.getElementById('topology-svg') ?
+ document.getElementById('topology-svg').getBoundingClientRect() :
+ svgSize;
+ }
- const nodeHeight = target.getBoundingClientRect().height;
- const nodeWidth = target.getBoundingClientRect().width;
+ constrain(x, y, children=false) {
+ const svgSize = this.getSvgSize();
- const constraints = {
- top: svgBounds.top + (nodeHeight / 2),
- left: svgBounds.left + (nodeWidth / 2),
- bottom: svgBounds.bottom - (nodeHeight / 2),
- right: svgBounds.right - (nodeWidth / 2)
+ const nodeRect = children ?
+ Constants.nodeRectWithChildren :
+ Constants.nodeRect;
+
+ if(x < nodeRect.right + 2) {
+ x = nodeRect.right + 2;
+ }
+ else if(x > svgSize.width + nodeRect.left - 2) {
+ x = svgSize.width + nodeRect.left - 2;
+ }
+ if(y < -nodeRect.top + 2) {
+ y = -nodeRect.top + 2;
+ }
+ else if(y > svgSize.height - nodeRect.bottom - 2) {
+ y = svgSize.height - nodeRect.bottom - 2;
+ }
+
+ return {
+ x,
+ y
};
-
- if ( x > constraints.right || x < constraints.left ) return false;
-
- if ( y < constraints.top || y > constraints.bottom ) return false;
-
- return true;
}
render() {
@@ -147,9 +156,14 @@ class TopologyGraph extends React.Component {
y: 0
} : simNode(service.uuid);
+ const constrained = {
+ ...sNode,
+ ...this.constrain(sNode.x, sNode.y, service.children)
+ };
+
return ({
...service,
- ...sNode
+ ...constrained
});
});
@@ -188,10 +202,6 @@ class TopologyGraph extends React.Component {
? evt.changedTouches[0].pageY
: evt.clientY;
- if ( !this.isWithinSVGBounds(evt.target, x, y) ) {
- triggerMouseEvent(evt.target, 'mouseup');
- }
-
const offset = {
x: x - dragInfo.position.x,
y: y - dragInfo.position.y
@@ -229,12 +239,16 @@ class TopologyGraph extends React.Component {
};
};
+ const onTitleClick = (serviceUUID) =>
+ this.props.onNodeTitleClick(serviceUUID);
+
const renderedNodes = nodesData.map((n, index) => (
@@ -255,7 +269,7 @@ class TopologyGraph extends React.Component {
onMouseUp={onDragEnd}
onTouchEnd={onDragEnd}
onTouchCancel={onDragEnd}
- className='topology-svg'
+ id='topology-svg'
>
{renderedNodes}
@@ -270,6 +284,7 @@ class TopologyGraph extends React.Component {
TopologyGraph.propTypes = {
onQuickActions: React.PropTypes.func,
+ onNodeTitleClick: React.PropTypes.func,
services: React.PropTypes.array
};