diff --git a/client/app/scripts/components/node-details.js b/client/app/scripts/components/node-details.js
index a9ad0dc1b9..44f1b30da6 100644
--- a/client/app/scripts/components/node-details.js
+++ b/client/app/scripts/components/node-details.js
@@ -130,7 +130,6 @@ export default class NodeDetails extends React.Component {
renderDetails() {
const details = this.props.details;
- const showSummary = (details.metadata || details.metrics || details.docker_labels) !== undefined;
const showControls = details.controls && details.controls.length > 0;
const nodeColor = getNodeColorDark(details.rank, details.label, details.pseudo);
const {error, pending} = (this.props.nodeControlStatus || {});
@@ -166,10 +165,13 @@ export default class NodeDetails extends React.Component {
}
- {showSummary &&
+ {details.metrics &&
Status
- {details.metrics &&
}
- {details.metadata &&
}
+
+
}
+ {details.metadata &&
}
{details.children && details.children.map(children => {
diff --git a/client/app/scripts/components/node-details/node-details-health-overflow.js b/client/app/scripts/components/node-details/node-details-health-overflow.js
index 32624d631e..76fcea7f8c 100644
--- a/client/app/scripts/components/node-details/node-details-health-overflow.js
+++ b/client/app/scripts/components/node-details/node-details-health-overflow.js
@@ -3,15 +3,23 @@ import React from 'react';
import NodeDetailsHealthOverflowItem from './node-details-health-overflow-item';
export default class NodeDetailsHealthOverflow extends React.Component {
+
+ constructor(props, context) {
+ super(props, context);
+ this.handleClick = this.handleClick.bind(this);
+ }
+
+ handleClick(ev) {
+ ev.preventDefault();
+ this.props.handleClick();
+ }
+
render() {
const items = this.props.items.slice(0, 4);
return (
-
+
{items.map(item =>
)}
-
- Show more
-
);
}
diff --git a/client/app/scripts/components/node-details/node-details-health.js b/client/app/scripts/components/node-details/node-details-health.js
index cb7cf1d4db..811b195643 100644
--- a/client/app/scripts/components/node-details/node-details-health.js
+++ b/client/app/scripts/components/node-details/node-details-health.js
@@ -1,5 +1,6 @@
import React from 'react';
+import ShowMore from '../show-more';
import NodeDetailsHealthOverflow from './node-details-health-overflow';
import NodeDetailsHealthItem from './node-details-health-item';
@@ -13,8 +14,7 @@ export default class NodeDetailsHealth extends React.Component {
this.handleClickMore = this.handleClickMore.bind(this);
}
- handleClickMore(ev) {
- ev.preventDefault();
+ handleClickMore() {
const expanded = !this.state.expanded;
this.setState({expanded});
}
@@ -25,17 +25,21 @@ export default class NodeDetailsHealth extends React.Component {
const primeMetrics = metrics.slice(0, primeCutoff);
const overflowMetrics = metrics.slice(primeCutoff);
const showOverflow = overflowMetrics.length > 0 && !this.state.expanded;
- const showLess = this.state.expanded;
const flexWrap = showOverflow || !this.state.expanded ? 'nowrap' : 'wrap';
const justifyContent = showOverflow || !this.state.expanded ? 'space-around' : 'flex-start';
+ const notShown = overflowMetrics.length;
return (
- {primeMetrics.map(item => {
- return
;
- })}
- {showOverflow &&
}
- {showLess &&
show less
}
+
+ {primeMetrics.map(item => {
+ return ;
+ })}
+ {showOverflow && this.handleClickMore()} />}
+
+
this.handleClickMore()} collection={this.props.metrics}
+ expanded={this.state.expanded} notShown={notShown} hideNumber />
);
}
diff --git a/client/app/scripts/components/node-details/node-details-info.js b/client/app/scripts/components/node-details/node-details-info.js
index 6df895cded..cf85a58d2f 100644
--- a/client/app/scripts/components/node-details/node-details-info.js
+++ b/client/app/scripts/components/node-details/node-details-info.js
@@ -1,5 +1,7 @@
import React from 'react';
+import ShowMore from '../show-more';
+
export default class NodeDetailsInfo extends React.Component {
constructor(props, context) {
@@ -10,8 +12,7 @@ export default class NodeDetailsInfo extends React.Component {
this.handleClickMore = this.handleClickMore.bind(this);
}
- handleClickMore(ev) {
- ev.preventDefault();
+ handleClickMore() {
const expanded = !this.state.expanded;
this.setState({expanded});
}
@@ -19,11 +20,9 @@ export default class NodeDetailsInfo extends React.Component {
render() {
let rows = (this.props.rows || []);
const prime = rows.filter(row => row.prime);
- let expandText = 'Show less';
- let showExpand = this.state.expanded;
+ let notShown = 0;
if (!this.state.expanded && prime.length < rows.length) {
- expandText = 'Show more';
- showExpand = true;
+ notShown = rows.length - prime.length;
rows = prime;
}
return (
@@ -40,7 +39,8 @@ export default class NodeDetailsInfo extends React.Component {
);
})}
- {showExpand &&
{expandText}
}
+
this.handleClickMore()} collection={this.props.rows}
+ expanded={this.state.expanded} notShown={notShown} />
);
}
diff --git a/client/app/scripts/components/node-details/node-details-table.js b/client/app/scripts/components/node-details/node-details-table.js
index 7164d471b9..c9e1863a5d 100644
--- a/client/app/scripts/components/node-details/node-details-table.js
+++ b/client/app/scripts/components/node-details/node-details-table.js
@@ -1,6 +1,7 @@
import _ from 'lodash';
import React from 'react';
+import ShowMore from '../show-more';
import NodeDetailsTableNodeLink from './node-details-table-node-link';
import NodeDetailsTableNodeMetric from './node-details-table-node-metric';
@@ -25,8 +26,7 @@ export default class NodeDetailsTable extends React.Component {
this.setState({sortBy, sortedDesc});
}
- handleLimitClick(ev) {
- ev.preventDefault();
+ handleLimitClick() {
const limit = this.state.limit ? 0 : this.DEFAULT_LIMIT;
this.setState({limit});
}
@@ -115,6 +115,8 @@ export default class NodeDetailsTable extends React.Component {
}
return
;
}
+ // empty cell to complete the row for proper hover
+ return
| ;
});
}
@@ -122,8 +124,8 @@ export default class NodeDetailsTable extends React.Component {
const headers = this.renderHeaders();
let nodes = _.sortByAll(this.props.nodes, this.getValueForSortBy, 'label', this.getMetaDataSorters());
const limited = nodes && this.state.limit > 0 && nodes.length > this.state.limit;
- const showLimitAction = nodes && (limited || (this.state.limit === 0 && nodes.length > this.DEFAULT_LIMIT));
- const limitActionText = limited ? 'Show more' : 'Show less';
+ const expanded = this.state.limit === 0;
+ const notShown = nodes.length - this.DEFAULT_LIMIT;
if (this.state.sortedDesc) {
nodes.reverse();
}
@@ -151,7 +153,7 @@ export default class NodeDetailsTable extends React.Component {
})}
- {showLimitAction &&
{limitActionText}
}
+
this.handleLimitClick()} collection={this.props.nodes} expanded={expanded} notShown={notShown} />
);
}
diff --git a/client/app/scripts/components/show-more.js b/client/app/scripts/components/show-more.js
new file mode 100644
index 0000000000..8da206f33a
--- /dev/null
+++ b/client/app/scripts/components/show-more.js
@@ -0,0 +1,30 @@
+import React from 'react';
+
+export default class ShowMore extends React.Component {
+
+ constructor(props, context) {
+ super(props, context);
+ this.handleClick = this.handleClick.bind(this);
+ }
+
+ handleClick(ev) {
+ ev.preventDefault();
+ this.props.handleClick();
+ }
+
+ render() {
+ const { collection, notShown, expanded, hideNumber } = this.props;
+ const showLimitAction = collection && (expanded || notShown > 0);
+ const limitActionText = !hideNumber && !expanded && notShown > 0 ? `+${notShown}` : '';
+ const limitActionIcon = !expanded && notShown > 0 ? 'fa fa-caret-down' : 'fa fa-caret-up';
+
+ if (!showLimitAction) {
+ return