mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 01:31:17 +00:00
Pulls loading out into new cmp, adds delayed show for loading
This commit is contained in:
59
client/app/scripts/components/loading.js
Normal file
59
client/app/scripts/components/loading.js
Normal file
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { findTopologyById } from '../utils/topology-utils';
|
||||
import NodesError from '../charts/nodes-error';
|
||||
|
||||
|
||||
const LOADING_TEMPLATES = [
|
||||
'Loading THINGS',
|
||||
'Verifying THINGS',
|
||||
'Fetching THINGS',
|
||||
'Processing THINGS',
|
||||
'Reticulating THINGS',
|
||||
'Locating THINGS',
|
||||
'Optimizing THINGS',
|
||||
'Transporting THINGS',
|
||||
'Double checking THINGS',
|
||||
];
|
||||
|
||||
|
||||
export function getNodeType(topology, topologies) {
|
||||
if (!topology || topologies.size === 0) {
|
||||
return '';
|
||||
}
|
||||
let name = topology.get('name');
|
||||
if (topology.get('parentId')) {
|
||||
const parentTopology = findTopologyById(topologies, topology.get('parentId'));
|
||||
name = parentTopology.get('name');
|
||||
}
|
||||
return name.toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
function renderTemplate(nodeType, template) {
|
||||
return template.replace('THINGS', nodeType);
|
||||
}
|
||||
|
||||
|
||||
export class Loading extends React.Component {
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
template: _.sample(LOADING_TEMPLATES)
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { itemType, show } = this.props;
|
||||
const message = renderTemplate(itemType, this.state.template);
|
||||
return (
|
||||
<NodesError mainClassName="nodes-chart-loading" faIconClass="fa-circle-thin" hidden={!show}>
|
||||
<div className="heading">{message}</div>
|
||||
</NodesError>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +1,17 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import NodesChart from '../charts/nodes-chart';
|
||||
import NodesError from '../charts/nodes-error';
|
||||
import { findTopologyById, isTopologyEmpty } from '../utils/topology-utils';
|
||||
import { DelayedShow } from '../utils/delayed-show';
|
||||
import { Loading, getNodeType } from './loading';
|
||||
import { isTopologyEmpty } from '../utils/topology-utils';
|
||||
|
||||
const navbarHeight = 160;
|
||||
const marginTop = 0;
|
||||
const detailsWidth = 450;
|
||||
|
||||
|
||||
const LOADING_TEMPLATES = [
|
||||
'Loading THINGS',
|
||||
'Verifying THINGS',
|
||||
'Fetching THINGS',
|
||||
'Processing THINGS',
|
||||
'Reticulating THINGS',
|
||||
'Locating THINGS',
|
||||
'Optimizing THINGS',
|
||||
'Transporting THINGS',
|
||||
'Double checking THINGS',
|
||||
];
|
||||
|
||||
|
||||
function renderTemplate(nodeType, template) {
|
||||
return template.replace('THINGS', nodeType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dynamic coords precision based on topology size
|
||||
*/
|
||||
@@ -47,29 +30,14 @@ function getLayoutPrecision(nodesCount) {
|
||||
return precision;
|
||||
}
|
||||
|
||||
function getNodeType(topology, topologies) {
|
||||
if (!topology || topologies.size === 0) {
|
||||
return '';
|
||||
}
|
||||
let name = topology.get('name');
|
||||
if (topology.get('parentId')) {
|
||||
const parentTopology = findTopologyById(topologies, topology.get('parentId'));
|
||||
name = parentTopology.get('name');
|
||||
}
|
||||
return name.toLowerCase();
|
||||
}
|
||||
|
||||
class Nodes extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
this.handleResize = this.handleResize.bind(this);
|
||||
|
||||
const [topologiesLoadingTemplate, nodeLoadingTemplate] = _.sampleSize(LOADING_TEMPLATES, 2);
|
||||
this.state = {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight - navbarHeight - marginTop,
|
||||
topologiesLoadingTemplate,
|
||||
nodeLoadingTemplate,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -97,28 +65,20 @@ class Nodes extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderLoading(message, show) {
|
||||
return (
|
||||
<NodesError mainClassName="nodes-chart-loading" faIconClass="fa-circle-thin" hidden={!show}>
|
||||
<div className="heading">{message}</div>
|
||||
</NodesError>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { nodes, selectedNodeId, topologyEmpty, topologiesLoaded, nodesLoaded, topologies,
|
||||
topology } = this.props;
|
||||
const layoutPrecision = getLayoutPrecision(nodes.size);
|
||||
const hasSelectedNode = selectedNodeId && nodes.has(selectedNodeId);
|
||||
const topologyLoadingMessage = renderTemplate('topologies',
|
||||
this.state.topologiesLoadingTemplate);
|
||||
const nodeLoadingMessage = renderTemplate(getNodeType(topology, topologies),
|
||||
this.state.nodeLoadingTemplate);
|
||||
|
||||
return (
|
||||
<div className="nodes-wrapper">
|
||||
{this.renderLoading(topologyLoadingMessage, !topologiesLoaded)}
|
||||
{this.renderLoading(nodeLoadingMessage, topologiesLoaded && !nodesLoaded)}
|
||||
<DelayedShow delay={1000} show={!topologiesLoaded}>
|
||||
<Loading itemType="topologies" show={!topologiesLoaded} />
|
||||
<Loading
|
||||
itemType={getNodeType(topology, topologies)}
|
||||
show={topologiesLoaded && !nodesLoaded} />
|
||||
</DelayedShow>
|
||||
{this.renderEmptyTopologyError(topologiesLoaded && nodesLoaded && topologyEmpty)}
|
||||
<NodesChart {...this.state}
|
||||
detailsWidth={detailsWidth}
|
||||
|
||||
55
client/app/scripts/utils/delayed-show.js
Normal file
55
client/app/scripts/utils/delayed-show.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
|
||||
|
||||
export class DelayedShow extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
show: false
|
||||
};
|
||||
|
||||
if (props.show) {
|
||||
this.scheduleShow();
|
||||
}
|
||||
}
|
||||
|
||||
scheduleShow() {
|
||||
this.showTimeout = setTimeout(() => this.setState({ show: true }), this.props.delay);
|
||||
}
|
||||
|
||||
cancelShow() {
|
||||
clearTimeout(this.showTimeout);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.show === this.props.show) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextProps.show) {
|
||||
this.scheduleShow();
|
||||
} else {
|
||||
this.cancelShow();
|
||||
this.setState({ show: false });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
const { show } = this.state;
|
||||
const style = {
|
||||
opacity: show ? 1 : 0,
|
||||
transition: 'opacity 0.5s ease-in-out',
|
||||
};
|
||||
return (
|
||||
<div style={style}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DelayedShow.defaultProps = {
|
||||
delay: 1000
|
||||
};
|
||||
Reference in New Issue
Block a user