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

281 lines
7.6 KiB
React
Raw Normal View History

import React from 'react'
import {connect} from 'react-redux'
import {Link} from 'react-router'
2018-07-16 22:53:57 +02:00
import RoutesTable from './table'
2018-07-20 11:32:48 +02:00
import {RoutesPaginator,
RoutesPaginationInfo} from './pagination'
2018-07-16 22:53:57 +02:00
2018-07-16 10:52:41 +02:00
import {fetchRoutesReceived,
fetchRoutesFiltered,
fetchRoutesNotExported} from './actions'
2018-08-03 18:51:50 +02:00
import {makeLinkProps} from './pagination'
2018-07-16 10:52:41 +02:00
// Constants
import {ROUTES_RECEIVED,
ROUTES_FILTERED,
ROUTES_NOT_EXPORTED} from './actions';
2018-07-16 19:49:54 +02:00
const RoutesHeader = (props) => {
const type = props.type;
const color = {
[ROUTES_RECEIVED]: "green",
[ROUTES_FILTERED]: "orange",
[ROUTES_NOT_EXPORTED]: "red"
}[type];
const rtype = {
[ROUTES_RECEIVED]: "accepted",
[ROUTES_FILTERED]: "filtered",
[ROUTES_NOT_EXPORTED]: "not exported"
}[type];
return (<p style={{"color": color, "textTransform": "uppercase"}}>
Routes {rtype}
</p>);
};
/*
* Render a RoutesView:
* The routes view is a composit of:
* - A header
* - The Routes Table
* - A Paginator
*/
class RoutesView extends React.Component {
2018-07-23 15:24:24 +02:00
constructor(props) {
super(props);
}
dispatchFetchRoutes() {
2018-07-16 10:52:41 +02:00
const type = this.props.type;
// Depending on the component's configuration, dispatch
// routes fetching
const fetchRoutes = {
[ROUTES_RECEIVED]: fetchRoutesReceived,
[ROUTES_FILTERED]: fetchRoutesFiltered,
[ROUTES_NOT_EXPORTED]: fetchRoutesNotExported,
}[type];
2018-07-16 10:52:41 +02:00
// Gather required params
const params = this.props.routes[type];
const rsId = this.props.routeserverId;
const pId = this.props.protocolId;
const query = this.props.filterQuery;
// Make request
2018-08-03 17:04:31 +02:00
2018-08-03 19:26:49 +02:00
// Handle special case, when on demand loading is enabled,
2018-08-03 17:04:31 +02:00
// we defer this dispatch, until an user interaction.
2018-08-03 18:58:49 +02:00
if (!params.loadRoutes) {
2018-08-03 17:04:31 +02:00
return; // We are done here.
}
// Otherwise, just dispatch the request:
2018-07-16 10:52:41 +02:00
this.props.dispatch(fetchRoutes(rsId, pId, params.page, query));
}
2018-07-23 11:38:39 +02:00
/*
* Diff props and this.props to check if we need to
* dispatch another fetch routes
*/
routesNeedFetch(props) {
const type = this.props.type;
2018-08-03 18:51:50 +02:00
const nextParams = this.props.routes[type];
const params = props.routes[type]; // Previous props
2018-07-23 11:38:39 +02:00
2018-08-03 18:51:50 +02:00
if (this.props.filterQuery != props.filterQuery || // Pagination
params.page != nextParams.page || // Query
params.loadRoutes != nextParams.loadRoutes) {
return true;
2018-07-23 11:38:39 +02:00
}
2018-08-03 18:51:50 +02:00
2018-07-23 11:38:39 +02:00
return false;
}
componentDidMount() {
this.dispatchFetchRoutes();
}
componentDidUpdate(prevProps) {
2018-08-03 14:51:45 +02:00
const scrollAnchor = this.refs.scrollAnchor;
2018-07-23 11:38:39 +02:00
if (this.routesNeedFetch(prevProps)) {
this.dispatchFetchRoutes();
2018-08-03 14:51:45 +02:00
if (scrollAnchor) {
scrollAnchor.scrollIntoView({
behaviour: "smooth",
block: "start",
});
}
2018-07-23 11:38:39 +02:00
}
}
2018-08-03 17:04:31 +02:00
render() {
2018-07-16 19:49:54 +02:00
const type = this.props.type;
2018-07-16 22:53:57 +02:00
const state = this.props.routes[type];
2018-07-20 11:32:48 +02:00
const queryParam = {
[ROUTES_RECEIVED]: "pr",
[ROUTES_FILTERED]: "pf",
[ROUTES_NOT_EXPORTED]: "pn",
}[type];
const name = {
[ROUTES_RECEIVED]: "routes-received",
[ROUTES_FILTERED]: "routes-filtered",
[ROUTES_NOT_EXPORTED]: "routes-not-exported",
}[type];
2018-07-16 22:53:57 +02:00
2018-08-03 18:58:49 +02:00
if (!state.loadRoutes) {
2018-08-03 17:04:31 +02:00
// In case it was not yet requested, render a trigger
// and defer routesFetching until a user interaction has
// occured.
return this.renderLoadTrigger();
}
2018-07-16 22:53:57 +02:00
if (state.loading) {
return null;
}
if (state.totalResults == 0) {
return null;
}
2018-08-03 17:04:31 +02:00
// Render the routes card
return (
2018-07-23 15:24:24 +02:00
<div className={`card routes-view ${name}`}>
2018-08-03 17:04:31 +02:00
<div className="row">
<div className="col-md-6">
<a name={name} id={name} ref="scrollAnchor">
<RoutesHeader type={type} />
</a>
2018-07-20 11:32:48 +02:00
</div>
2018-08-03 17:04:31 +02:00
<div className="col-md-6">
<RoutesPaginationInfo page={state.page}
pageSize={state.pageSize}
totalPages={state.totalPages}
totalResults={state.totalResults} />
</div>
</div>
2018-07-25 15:46:06 +02:00
<RoutesTable type={type} routes={state.routes} />
2018-07-20 11:32:48 +02:00
<center>
2018-08-03 17:04:31 +02:00
<RoutesPaginator page={state.page} totalPages={state.totalPages}
queryParam={queryParam}
anchor={name} />
2018-07-20 11:32:48 +02:00
</center>
2018-07-30 22:59:59 +02:00
</div>
);
}
2018-08-03 17:04:31 +02:00
renderLoadTrigger() {
const type = this.props.type;
const state = this.props.routes[type];
const name = {
[ROUTES_RECEIVED]: "routes-received",
[ROUTES_FILTERED]: "routes-filtered",
[ROUTES_NOT_EXPORTED]: "routes-not-exported",
}[type];
// This is an artificial delay, to make the user wait until
// filtered and recieved routes are fetched
if (!state.otherLoaded) {
return null;
}
2018-08-03 18:51:50 +02:00
const linkProps = makeLinkProps({
loadNotExported: true,
anchor: "routes-not-exported",
page: this.props.routes.notExported.page,
pageReceived: this.props.routes.received.page,
pageFiltered: this.props.routes.filtered.page,
pageNotExported: this.props.routes.notExported.page,
routing: this.props.routing
});
2018-08-03 17:04:31 +02:00
return (
<div className={`card routes-view ${name}`}>
<div className="row">
<div className="col-md-6">
<a name={name} id={name} ref="scrollAnchor">
<RoutesHeader type={type} />
</a>
</div>
</div>
<p className="help">
Due to the high amount of routes not exported,
2018-08-03 18:51:50 +02:00
they are only fetched on demand.
2018-08-03 17:04:31 +02:00
</p>
2018-08-03 18:25:28 +02:00
2018-08-03 18:51:50 +02:00
<Link to={linkProps} className="btn btn-block btn-danger">
Load Routes Not Exported
</Link>
2018-08-03 17:04:31 +02:00
</div>
);
}
}
export default connect(
2018-07-16 10:52:41 +02:00
(state) => {
let received = {
routes: state.routes.received,
2018-08-03 17:04:31 +02:00
requested: state.routes.receivedRequested,
2018-07-16 10:52:41 +02:00
loading: state.routes.receivedLoading,
page: state.routes.receivedPage,
2018-07-20 11:32:48 +02:00
pageSize: state.routes.receivedPageSize,
2018-07-16 10:52:41 +02:00
totalPages: state.routes.receivedTotalPages,
totalResults: state.routes.receivedTotalResults,
2018-08-03 18:25:28 +02:00
loadRoutes: true,
2018-07-16 10:52:41 +02:00
};
let filtered = {
routes: state.routes.filtered,
loading: state.routes.filteredLoading,
2018-08-03 17:04:31 +02:00
requested: state.routes.filteredRequested,
2018-07-16 10:52:41 +02:00
page: state.routes.filteredPage,
2018-07-20 11:32:48 +02:00
pageSize: state.routes.filteredPageSize,
2018-07-16 10:52:41 +02:00
totalPages: state.routes.filteredTotalPages,
totalResults: state.routes.filteredTotalResults,
2018-08-03 18:25:28 +02:00
loadRoutes: true,
2018-07-16 10:52:41 +02:00
};
let notExported = {
routes: state.routes.notExported,
2018-08-03 18:25:28 +02:00
requested: state.routes.notExportedRequested,
2018-07-16 10:52:41 +02:00
loading: state.routes.notExportedLoading,
page: state.routes.notExportedPage,
2018-07-20 11:32:48 +02:00
pageSize: state.routes.notExportedPageSize,
2018-07-16 10:52:41 +02:00
totalPages: state.routes.notExportedTotalPages,
totalResults: state.routes.notExportedTotalResults,
2018-08-03 18:25:28 +02:00
2018-08-03 18:58:49 +02:00
loadRoutes: state.routes.loadNotExported ||
!state.config.noexport_load_on_demand,
2018-08-03 18:25:28 +02:00
2018-08-03 17:04:31 +02:00
otherLoaded: state.routes.receivedRequested &&
!state.routes.receivedLoading &&
state.routes.filteredRequested &&
!state.routes.filteredLoading
2018-07-16 10:52:41 +02:00
};
return({
filterQuery: state.routes.filterQuery,
routes: {
[ROUTES_RECEIVED]: received,
[ROUTES_FILTERED]: filtered,
[ROUTES_NOT_EXPORTED]: notExported
2018-07-16 10:52:41 +02:00
},
2018-08-03 18:51:50 +02:00
routing: state.routing.locationBeforeTransitions
2018-07-16 10:52:41 +02:00
});
}
)(RoutesView);