import { OctopusArms, inboundAlignment } from './util/OctopusArms.jsx';
import { displayName, metricToFormatter } from './util/Utils.js';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import Grid from '@material-ui/core/Grid';
import PropTypes from 'prop-types';
import React from 'react';
import RootRef from '@material-ui/core/RootRef';
import { StyledProgress } from './util/Progress.jsx';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableRow from '@material-ui/core/TableRow';
import Typography from '@material-ui/core/Typography';
import _get from 'lodash/get';
import _isEmpty from 'lodash/isEmpty';
import _isNil from 'lodash/isNil';
import _size from 'lodash/size';
import _slice from 'lodash/slice';
import _sortBy from 'lodash/sortBy';
import _take from 'lodash/take';
import { getSuccessRateClassification } from './util/MetricUtils.jsx';
import { withStyles } from '@material-ui/core/styles';
const maxNumNeighbors = 6; // max number of neighbor nodes to show in the octopus graph
const styles = () => ({
graphContainer: {
overflowX: 'auto',
padding: '16px 0',
},
graph: {
maxWidth: '974px',
minWidth: '974px',
marginLeft: 'auto',
marginRight: 'auto',
},
centerNode: {
width: '244px',
},
neighborNode: {
width: '220px',
},
collapsedNeighborName: {
paddingTop: '10px',
},
});
class Octopus extends React.Component {
constructor(props) {
super(props);
this.upstreamsContainer = React.createRef();
this.downstreamsContainer = React.createRef();
this.upstreamsRefs = [];
this.downstreamsRefs = [];
}
getNeighborDisplayData = neighbors => {
// only display maxNumNeighbors neighboring nodes in the octopus graph,
// otherwise it will be really tall
// even though _sortBy is a stable sort, the order that this data is returned by the API
// can change, so the original order of items can change; this means we have to sort by
// name and by SR to ensure an actual stable sort
const upstreams = _sortBy(_sortBy(neighbors.upstream, displayName), n => n.successRate);
const downstreams = _sortBy(_sortBy(neighbors.downstream, displayName), n => n.successRate);
const display = {
upstreams: {
displayed: upstreams,
collapsed: [],
},
downstreams: {
displayed: downstreams,
collapsed: [],
},
};
if (_size(upstreams) > maxNumNeighbors) {
display.upstreams.displayed = _take(upstreams, maxNumNeighbors);
display.upstreams.collapsed = _slice(upstreams, maxNumNeighbors, _size(upstreams));
}
if (_size(downstreams) > maxNumNeighbors) {
display.downstreams.displayed = _take(downstreams, maxNumNeighbors);
display.downstreams.collapsed = _slice(downstreams, maxNumNeighbors, _size(downstreams));
}
return display;
}
addElementToRefsList = (element, index, isOutbound, type = 'neighbor') => {
if (element && (type !== 'main')) {
if (isOutbound) {
this.downstreamsRefs[index] = element;
} else {
this.upstreamsRefs[index] = element;
}
}
}
linkedResourceTitle = (resource, display) => {
// trafficsplit leaf resources cannot be linked
if (_isNil(resource.namespace) || resource.isLeafService) { return display; }
const { api: { ResourceLink } } = this.props;
return ;
}
renderResourceCard(resource, type, index, isOutbound) {
const { classes } = this.props;
const display = displayName(resource);
const classification = getSuccessRateClassification(resource.successRate);
const Progress = StyledProgress(classification);
// if the resource only has TCP stats, display those instead
let showTcp = false;
// trafficsplit leaf with zero traffic should still show HTTP stats
if (_isNil(resource.successRate) && _isNil(resource.requestRate) &&
resource.type !== 'service') {
showTcp = true;
}
return (
this.addElementToRefsList(el, index, isOutbound, type)} key={`${resource.type}-${resource.name}`}>
{ this.linkedResourceTitle(resource, display) }