1
0
mirror of https://github.com/alice-lg/alice-lg.git synced 2024-05-11 05:55:03 +00:00

247 lines
7.0 KiB
React
Raw Normal View History

2017-05-16 13:34:00 +02:00
2018-08-05 15:53:46 +02:00
import _ from 'underscore'
2018-07-23 19:55:26 +02:00
import {debounce} from "underscore"
2017-05-16 13:34:00 +02:00
import React from 'react'
import {connect} from 'react-redux'
import {Link} from 'react-router'
2018-09-16 20:07:35 +02:00
import {push, replace} from 'react-router-redux'
2017-05-16 13:34:00 +02:00
import Details from '../details'
import Status from '../status'
import PageHeader from 'components/page-header'
2018-07-27 18:18:48 +02:00
import {apiCacheStatus} from 'components/api-status/cache'
2017-05-16 13:34:00 +02:00
import ProtocolName
from 'components/routeservers/protocols/name'
import SearchInput from 'components/search-input'
2018-08-05 15:53:46 +02:00
import RoutesView from './view'
import QuickLinks from './quick-links'
import RelatedPeers from './related-peers'
2018-08-05 12:27:42 +02:00
2017-05-16 13:34:00 +02:00
import BgpAttributesModal
from './bgp-attributes-modal'
2018-07-16 22:53:57 +02:00
import RoutesLoadingIndicator from './loading-indicator'
2017-05-16 13:34:00 +02:00
// Actions
2018-07-23 19:55:26 +02:00
import {setFilterQueryValue}
from './actions'
2017-05-16 13:34:00 +02:00
import {loadRouteserverProtocol}
from 'components/routeservers/actions'
2018-07-16 10:52:41 +02:00
// Constants
import {ROUTES_RECEIVED,
ROUTES_FILTERED,
ROUTES_NOT_EXPORTED} from './actions';
2018-08-03 18:25:28 +02:00
const makeQueryLinkProps = function(routing, query, loadNotExported) {
// Load not exported routes flag
const ne = loadNotExported ? 1 : 0;
2018-07-23 19:55:26 +02:00
// As we need to reset the pagination, we can just
2018-08-03 18:25:28 +02:00
// ommit these other parameters and just use pathname + query + ne
2018-07-23 19:55:26 +02:00
return {
pathname: routing.pathname,
2018-08-03 18:25:28 +02:00
search: `?ne=${ne}&q=${query}`
2018-07-23 19:55:26 +02:00
};
}
/*
* Check if the routes view is empty, (while nothing is,
* loading) and show info screen.
*/
const RoutesViewEmpty = (props) => {
const isLoading = props.routes.received.loading ||
props.routes.filtered.loading ||
props.routes.notExported.loading;
if (isLoading) {
return null; // We are not a loading indicator.
}
2018-08-03 19:26:49 +02:00
if (!props.loadNotExported) {
return null; // There may be routes matching the query in there!
}
2018-07-23 19:55:26 +02:00
const hasContent = props.routes.received.totalResults > 0 ||
props.routes.filtered.totalResults > 0 ||
props.routes.notExported.totalResults > 0;
if (hasContent) {
return null; // Nothing to do then.
}
// Show info screen
return (
<div className="card info-result-empty">
<h4>No routes found matching your query.</h4>
<p>Please check if your query is too restrictive.</p>
</div>
);
}
2017-05-16 13:34:00 +02:00
class RoutesPage extends React.Component {
2018-07-23 19:55:26 +02:00
constructor(props) {
super(props);
// Create debounced dispatch, as we don't want to flood
// the server with API queries
this.debouncedDispatch = debounce(this.props.dispatch, 350);
}
2017-05-16 13:34:00 +02:00
setFilter(value) {
this.props.dispatch(
2018-07-23 19:55:26 +02:00
setFilterQueryValue(value)
2017-05-16 13:34:00 +02:00
);
2018-07-23 19:55:26 +02:00
2018-09-16 20:07:35 +02:00
this.debouncedDispatch(replace(makeQueryLinkProps(
2018-08-03 18:25:28 +02:00
this.props.routing, value, this.props.loadNotExported
2018-07-23 19:55:26 +02:00
)));
2017-05-16 13:34:00 +02:00
}
componentDidMount() {
// Assert neighbors for RS are loaded
2017-05-16 13:34:00 +02:00
this.props.dispatch(
loadRouteserverProtocol(parseInt(this.props.params.routeserverId))
);
}
render() {
2018-07-27 18:18:48 +02:00
let cacheStatus = apiCacheStatus(this.props.routes.received.apiStatus);
if (this.props.anyLoading) {
cacheStatus = null;
}
2018-08-05 15:53:46 +02:00
// We have to shift the layout a bit, to make room for
// the related peers tabs
let pageClass = "routeservers-page";
if (this.props.relatedPeers.length > 1) {
pageClass += " has-related-peers";
}
2017-05-16 13:34:00 +02:00
return(
2018-08-05 15:53:46 +02:00
<div className={pageClass}>
2017-05-16 13:34:00 +02:00
<PageHeader>
<Link to={`/routeservers/${this.props.params.routeserverId}`}>
<Details routeserverId={this.props.params.routeserverId} />
</Link>
<span className="spacer">&raquo;</span>
<ProtocolName routeserverId={this.props.params.routeserverId}
protocolId={this.props.params.protocolId} />
</PageHeader>
<BgpAttributesModal />
<div className="row details-main">
<div className="col-md-8">
<div className="card">
2018-08-05 15:53:46 +02:00
<RelatedPeers peers={this.props.relatedPeers}
protocolId={this.props.params.protocolId}
routeserverId={this.props.params.routeserverId} />
2017-05-16 13:34:00 +02:00
<SearchInput
2018-07-23 19:55:26 +02:00
value={this.props.filterValue}
placeholder="Filter by Network or BGP next-hop"
2017-05-16 13:34:00 +02:00
onChange={(e) => this.setFilter(e.target.value)} />
</div>
2018-08-05 12:27:42 +02:00
<QuickLinks routes={this.props.routes} />
2018-08-03 19:26:49 +02:00
<RoutesViewEmpty routes={this.props.routes}
loadNotExported={this.props.loadNotExported} />
2018-07-23 19:55:26 +02:00
<RoutesView
2018-07-16 22:53:57 +02:00
type={ROUTES_FILTERED}
routeserverId={this.props.params.routeserverId}
protocolId={this.props.params.protocolId} />
<RoutesView
2018-07-16 22:53:57 +02:00
type={ROUTES_RECEIVED}
routeserverId={this.props.params.routeserverId}
protocolId={this.props.params.protocolId} />
<RoutesView
2018-07-16 10:52:41 +02:00
type={ROUTES_NOT_EXPORTED}
routeserverId={this.props.params.routeserverId}
protocolId={this.props.params.protocolId} />
2018-07-16 22:53:57 +02:00
<RoutesLoadingIndicator />
2017-05-16 13:34:00 +02:00
</div>
<div className="col-md-4">
<div className="card">
2018-07-27 18:18:48 +02:00
<Status routeserverId={this.props.params.routeserverId}
cacheStatus={cacheStatus} />
2017-05-16 13:34:00 +02:00
</div>
</div>
</div>
</div>
);
}
}
export default connect(
2018-08-05 15:53:46 +02:00
(state, props) => {
const protocolId = props.params.protocolId;
const rsId = parseInt(props.params.routeserverId, 10);
const neighbors = state.routeservers.protocols[rsId];
const neighbor = _.findWhere(neighbors, {id: protocolId});
// Find related peers. Peers belonging to the same AS.
let relatedPeers = [];
if (neighbor) {
2018-08-05 16:28:48 +02:00
relatedPeers = _.where(neighbors, {asn: neighbor.asn,
state: "up"});
2018-08-05 15:53:46 +02:00
}
2018-07-16 10:52:41 +02:00
let received = {
loading: state.routes.receivedLoading,
totalResults: state.routes.receivedTotalResults,
2018-07-27 18:18:48 +02:00
apiStatus: state.routes.receivedApiStatus
2018-07-16 10:52:41 +02:00
};
let filtered = {
loading: state.routes.filteredLoading,
totalResults: state.routes.filteredTotalResults,
2018-07-27 18:18:48 +02:00
apiStatus: state.routes.filteredApiStatus
2018-07-16 10:52:41 +02:00
};
let notExported = {
loading: state.routes.notExportedLoading,
totalResults: state.routes.notExportedTotalResults,
2018-07-27 18:18:48 +02:00
apiStatus: state.routes.notExportedApiStatus
2018-07-16 10:52:41 +02:00
};
2018-07-27 18:18:48 +02:00
let anyLoading = state.routes.receivedLoading ||
state.routes.filteredLoading ||
state.routes.notExportedLoading;
2018-07-16 10:52:41 +02:00
return({
2018-07-23 19:55:26 +02:00
filterValue: state.routes.filterValue,
2018-07-16 10:52:41 +02:00
routes: {
[ROUTES_RECEIVED]: received,
[ROUTES_FILTERED]: filtered,
[ROUTES_NOT_EXPORTED]: notExported
2018-07-23 19:55:26 +02:00
},
2018-07-27 18:18:48 +02:00
routing: state.routing.locationBeforeTransitions,
2018-08-03 19:26:49 +02:00
loadNotExported: state.routes.loadNotExported ||
!state.config.noexport_load_on_demand,
2018-08-05 15:53:46 +02:00
anyLoading: anyLoading,
relatedPeers: relatedPeers
2018-07-16 10:52:41 +02:00
});
2017-05-16 13:34:00 +02:00
}
)(RoutesPage);