mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-05 03:01:11 +00:00
Merge pull request #1465 from weaveworks/truncate-container-envs
Limit tables to 20 rows
This commit is contained in:
@@ -2,15 +2,22 @@ import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { clickCloseDetails, clickShowTopologyForNode } from '../actions/app-actions';
|
||||
import { brightenColor, getNeutralColor, getNodeColorDark } from '../utils/color-utils';
|
||||
import { resetDocumentTitle, setDocumentTitle } from '../utils/title-utils';
|
||||
|
||||
import NodeDetailsControls from './node-details/node-details-controls';
|
||||
import NodeDetailsHealth from './node-details/node-details-health';
|
||||
import NodeDetailsInfo from './node-details/node-details-info';
|
||||
import NodeDetailsLabels from './node-details/node-details-labels';
|
||||
import NodeDetailsRelatives from './node-details/node-details-relatives';
|
||||
import NodeDetailsTable from './node-details/node-details-table';
|
||||
import { clickCloseDetails, clickShowTopologyForNode } from '../actions/app-actions';
|
||||
import { brightenColor, getNeutralColor, getNodeColorDark } from '../utils/color-utils';
|
||||
import { resetDocumentTitle, setDocumentTitle } from '../utils/title-utils';
|
||||
import Warning from './warning';
|
||||
|
||||
function getTruncationText(count) {
|
||||
return 'This section was too long to be handled efficiently and has been truncated'
|
||||
+ ` (${count} extra entries not included). We are working to remove this limitation.`;
|
||||
}
|
||||
|
||||
export class NodeDetails extends React.Component {
|
||||
|
||||
@@ -196,7 +203,13 @@ export class NodeDetails extends React.Component {
|
||||
if (table.rows.length > 0) {
|
||||
return (
|
||||
<div className="node-details-content-section" key={table.id}>
|
||||
<div className="node-details-content-section-header">{table.label}</div>
|
||||
<div className="node-details-content-section-header">
|
||||
{table.label}
|
||||
{table.truncationCount > 0 && <span
|
||||
className="node-details-content-section-header-warning">
|
||||
<Warning text={getTruncationText(table.truncationCount)} />
|
||||
</span>}
|
||||
</div>
|
||||
<NodeDetailsLabels rows={table.rows} />
|
||||
</div>
|
||||
);
|
||||
|
||||
39
client/app/scripts/components/warning.js
Normal file
39
client/app/scripts/components/warning.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
|
||||
class Warning extends React.Component {
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.state = {
|
||||
expanded: false
|
||||
};
|
||||
}
|
||||
|
||||
handleClick() {
|
||||
const expanded = !this.state.expanded;
|
||||
this.setState({ expanded });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { text } = this.props;
|
||||
const { expanded } = this.state;
|
||||
|
||||
const className = classnames('warning', {
|
||||
'warning-expanded': expanded
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={className} onClick={this.handleClick}>
|
||||
<div className="warning-wrapper">
|
||||
<span className="warning-icon fa fa-warning" title={text} />
|
||||
{expanded && <span className="warning-text">{text}</span>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Warning;
|
||||
@@ -1098,6 +1098,42 @@ h2 {
|
||||
}
|
||||
}
|
||||
|
||||
.warning {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
border: 1px dashed transparent;
|
||||
text-transform: none;
|
||||
border-radius: @border-radius;
|
||||
margin-left: 4px;
|
||||
|
||||
&-wrapper {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&-text {
|
||||
display: inline-block;
|
||||
color: @text-secondary-color;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
.btn-opacity;
|
||||
}
|
||||
|
||||
&-expanded {
|
||||
margin-left: 0;
|
||||
padding: 2px 4px;
|
||||
border-color: @text-tertiary-color;
|
||||
}
|
||||
|
||||
&-expanded &-icon {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
left: 2px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
|
||||
@@ -1,37 +1,62 @@
|
||||
package report
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/weaveworks/scope/common/mtime"
|
||||
)
|
||||
|
||||
// MaxTableRows sets the limit on the table size to render
|
||||
// TODO: this won't be needed once we send reports incrementally
|
||||
const (
|
||||
MaxTableRows = 20
|
||||
TruncationCountPrefix = "table_truncation_count_"
|
||||
)
|
||||
|
||||
// AddTable appends arbirary key-value pairs to the Node, returning a new node.
|
||||
func (node Node) AddTable(prefix string, labels map[string]string) Node {
|
||||
count := 0
|
||||
for key, value := range labels {
|
||||
if count >= MaxTableRows {
|
||||
break
|
||||
}
|
||||
node = node.WithLatest(prefix+key, mtime.Now(), value)
|
||||
count++
|
||||
}
|
||||
if len(labels) > MaxTableRows {
|
||||
truncationCount := fmt.Sprintf("%d", len(labels)-MaxTableRows)
|
||||
node = node.WithLatest(TruncationCountPrefix+prefix, mtime.Now(), truncationCount)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// ExtractTable returns the key-value pairs with the given prefix from this Node,
|
||||
func (node Node) ExtractTable(prefix string) map[string]string {
|
||||
result := map[string]string{}
|
||||
func (node Node) ExtractTable(prefix string) (rows map[string]string, truncationCount int) {
|
||||
rows = map[string]string{}
|
||||
truncationCount = 0
|
||||
node.Latest.ForEach(func(key, value string) {
|
||||
if strings.HasPrefix(key, prefix) {
|
||||
label := key[len(prefix):]
|
||||
result[label] = value
|
||||
rows[label] = value
|
||||
}
|
||||
})
|
||||
return result
|
||||
if str, ok := node.Latest.Lookup(TruncationCountPrefix + prefix); ok {
|
||||
if n, err := fmt.Sscanf(str, "%d", &truncationCount); n != 1 || err != nil {
|
||||
log.Warn("Unexpected truncation count format %q", str)
|
||||
}
|
||||
}
|
||||
return rows, truncationCount
|
||||
}
|
||||
|
||||
// Table is the type for a table in the UI.
|
||||
type Table struct {
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Rows []MetadataRow `json:"rows"`
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Rows []MetadataRow `json:"rows"`
|
||||
TruncationCount int `json:"truncationCount,omitempty"`
|
||||
}
|
||||
|
||||
type tablesByID []Table
|
||||
@@ -90,12 +115,13 @@ type TableTemplates map[string]TableTemplate
|
||||
func (t TableTemplates) Tables(node Node) []Table {
|
||||
var result []Table
|
||||
for _, template := range t {
|
||||
rows, truncationCount := node.ExtractTable(template.Prefix)
|
||||
table := Table{
|
||||
ID: template.ID,
|
||||
Label: template.Label,
|
||||
Rows: []MetadataRow{},
|
||||
ID: template.ID,
|
||||
Label: template.Label,
|
||||
Rows: []MetadataRow{},
|
||||
TruncationCount: truncationCount,
|
||||
}
|
||||
rows := node.ExtractTable(template.Prefix)
|
||||
keys := make([]string, 0, len(rows))
|
||||
for k := range rows {
|
||||
keys = append(keys, k)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package report_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@@ -16,9 +17,37 @@ func TestTables(t *testing.T) {
|
||||
nmd := report.MakeNode("foo1")
|
||||
|
||||
nmd = nmd.AddTable("foo_", want)
|
||||
have := nmd.ExtractTable("foo_")
|
||||
have, truncationCount := nmd.ExtractTable("foo_")
|
||||
|
||||
if truncationCount != 0 {
|
||||
t.Error("Table shouldn't had been truncated")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(want, have) {
|
||||
t.Error(test.Diff(want, have))
|
||||
}
|
||||
}
|
||||
|
||||
func TestTruncation(t *testing.T) {
|
||||
wantTruncationCount := 1
|
||||
want := map[string]string{}
|
||||
for i := 0; i < report.MaxTableRows+wantTruncationCount; i++ {
|
||||
key := fmt.Sprintf("key%d", i)
|
||||
value := fmt.Sprintf("value%d", i)
|
||||
want[key] = value
|
||||
}
|
||||
|
||||
nmd := report.MakeNode("foo1")
|
||||
|
||||
nmd = nmd.AddTable("foo_", want)
|
||||
_, truncationCount := nmd.ExtractTable("foo_")
|
||||
|
||||
if truncationCount != wantTruncationCount {
|
||||
t.Error(
|
||||
"Table should had been truncated by",
|
||||
wantTruncationCount,
|
||||
"and not",
|
||||
truncationCount,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user