initial details modal
This commit is contained in:
parent
462938db68
commit
0c87b8924f
55
ui/src/app/components/modal/Modal.js
Normal file
55
ui/src/app/components/modal/Modal.js
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
|
||||
export const ModalHeader = ({children, onDismiss}) => {
|
||||
return (
|
||||
<div className="modal-header">
|
||||
<button type="button"
|
||||
className="close"
|
||||
aria-label="Close"
|
||||
onClick={onDismiss}>
|
||||
<span aria-hidden="true">×</span></button>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export const ModalBody = ({children}) => {
|
||||
return (
|
||||
<div className="modal-body">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export const ModalFooter = ({children}) => {
|
||||
return(
|
||||
<div className="modal-footer">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export const Modal = ({
|
||||
children,
|
||||
onDismiss,
|
||||
className="",
|
||||
}) => {
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className="modal modal-open modal-show fade in" role="dialog">
|
||||
<div className="modal-dialog" role="document">
|
||||
<div className="modal-content">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="modal-backdrop fade in"
|
||||
onClick={onDismiss}></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Modal;
|
105
ui/src/app/components/routes/RouteDetailsModal.js
Normal file
105
ui/src/app/components/routes/RouteDetailsModal.js
Normal file
@ -0,0 +1,105 @@
|
||||
|
||||
import { useCallback }
|
||||
from 'react';
|
||||
|
||||
import { useRouteDetails }
|
||||
from 'app/context/routes';
|
||||
|
||||
import { Modal
|
||||
, ModalHeader
|
||||
, ModalBody
|
||||
, ModalFooter
|
||||
}
|
||||
from 'app/components/modal/Modal';
|
||||
|
||||
|
||||
const BgpCommunitiyLabel = ({community}) => {
|
||||
console.log("BGP COM LABEL:", community);
|
||||
return (<>Label</>);
|
||||
}
|
||||
|
||||
const RouteDetailsModal = () => {
|
||||
const [ route, setRoute ] = useRouteDetails();
|
||||
|
||||
const onDismiss = useCallback(() => setRoute(null), [setRoute]);
|
||||
|
||||
const attrs = route?.bgp;
|
||||
if (!attrs) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const communities = attrs.communities;
|
||||
const extCommunities = attrs.ext_communities;
|
||||
const largeCommunities = attrs.large_communities;
|
||||
|
||||
// As communities can be repeated, we can not use them
|
||||
// directly as keys, but may have to prepend a suffix.
|
||||
const communityKeyCnt = {};
|
||||
const communityKey = (community) => {
|
||||
const k = community.join(":");
|
||||
communityKeyCnt[k] = (communityKeyCnt[k]||0) + 1;
|
||||
return `${k}+${communityKeyCnt[k]}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className="bgp-attributes-modal"
|
||||
onDismiss={onDismiss}>
|
||||
<ModalHeader onDismiss={onDismiss}>
|
||||
<p>BGP Attributes for Network:</p>
|
||||
<h4>{route.network}</h4>
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<table className="table table-nolines">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Origin:</th><td>{attrs.origin}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Local Pref:</th><td>{attrs.local_pref}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Next Hop:</th><td>{attrs.next_hop}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>MED</th>
|
||||
<td>{attrs.med}</td>
|
||||
</tr>
|
||||
{attrs.as_path &&
|
||||
<tr>
|
||||
<th>AS Path:</th><td>{attrs.as_path.join(' ')}</td>
|
||||
</tr>}
|
||||
{communities.length > 0 &&
|
||||
<tr>
|
||||
<th>Communities:</th>
|
||||
<td>
|
||||
{communities.map((c) => <BgpCommunitiyLabel community={c} key={communityKey(c)} />)}
|
||||
</td>
|
||||
</tr>}
|
||||
{extCommunities.length > 0 &&
|
||||
<tr>
|
||||
<th>Ext. Communities:</th>
|
||||
<td>
|
||||
{extCommunities.map((c) => <BgpCommunitiyLabel community={c} key={communityKey(c)} />)}
|
||||
</td>
|
||||
</tr>}
|
||||
{largeCommunities.length > 0 &&
|
||||
<tr>
|
||||
<th>Large Communities:</th>
|
||||
<td>
|
||||
{largeCommunities.map((c) => <BgpCommunitiyLabel community={c} key={communityKey(c)} />)}
|
||||
</td>
|
||||
</tr>}
|
||||
</tbody>
|
||||
</table>
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<button className="btn btn-default"
|
||||
onClick={onDismiss}>Close</button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default RouteDetailsModal;
|
@ -33,6 +33,8 @@ import EmptyResults
|
||||
from 'app/components/routes/EmptyResults';
|
||||
import RoutesTable
|
||||
from 'app/components/routes/RoutesTable';
|
||||
import RouteDetailsModal
|
||||
from 'app/components/routes/RouteDetailsModal';
|
||||
import Paginator
|
||||
from 'app/components/pagination/Paginator';
|
||||
import PaginationInfo
|
||||
@ -42,7 +44,6 @@ import LoadingIndicator
|
||||
import WaitingText
|
||||
from 'app/components/spinners/WaitingText';
|
||||
|
||||
|
||||
const RoutesHeader = ({type}) => {
|
||||
const rtype = {
|
||||
[ROUTES_RECEIVED]: "accepted",
|
||||
@ -188,13 +189,14 @@ const Routes = () => {
|
||||
"#routes-not-exported": refNotExported,
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
<div className="routes-view">
|
||||
|
||||
<QuickLinks />
|
||||
<EmptyResults />
|
||||
|
||||
<RouteDetailsModal />
|
||||
|
||||
<div ref={refFiltered}>
|
||||
<RoutesFiltered />
|
||||
</div>
|
||||
|
@ -5,6 +5,8 @@ import { useCallback }
|
||||
|
||||
import { useConfig }
|
||||
from 'app/context/config';
|
||||
import { useSetRouteDetails }
|
||||
from 'app/context/routes';
|
||||
|
||||
import FilterReason
|
||||
from 'app/components/routes/FilterReason';
|
||||
@ -102,6 +104,7 @@ const RouteColumn = ({onClick, column, route}) => {
|
||||
|
||||
const RoutesTable = ({results}) => {
|
||||
const config = useConfig();
|
||||
const setRouteDetails = useSetRouteDetails();
|
||||
|
||||
const columns = config.routes_columns;
|
||||
const columnsOrder = config.routes_columns_order;
|
||||
@ -109,8 +112,8 @@ const RoutesTable = ({results}) => {
|
||||
const { routes } = results;
|
||||
|
||||
const showAttributesModal = useCallback((route) => {
|
||||
console.log("show attributes:", route);
|
||||
}, []);
|
||||
setRouteDetails(route);
|
||||
}, [setRouteDetails]);
|
||||
|
||||
if(!routes.length === 0) {
|
||||
return null;
|
||||
|
@ -137,8 +137,6 @@ const useFetchReceivedState = createFetchRoutesState(ROUTES_RECEIVED);
|
||||
const useFetchFilteredState = createFetchRoutesState(ROUTES_FILTERED);
|
||||
const useFetchNotExportedState = createFetchRoutesState(ROUTES_NOT_EXPORTED);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create routes provider makes a new routes provider
|
||||
* for a given context.
|
||||
@ -194,3 +192,24 @@ export const RoutesNotExportedProvider = createRoutesProvider(
|
||||
useFetchNotExportedState,
|
||||
);
|
||||
|
||||
/**
|
||||
* RouteDetails Context
|
||||
*/
|
||||
const RouteDetailsContext = createContext();
|
||||
|
||||
export const useRouteDetails = () => useContext(RouteDetailsContext);
|
||||
|
||||
export const useSetRouteDetails = () => useRouteDetails()[1];
|
||||
|
||||
export const RouteDetailsProvider = ({children}) => {
|
||||
const state = useState();
|
||||
return (
|
||||
<RouteDetailsContext.Provider value={state}>
|
||||
{children}
|
||||
</RouteDetailsContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@ import { NeighborProvider
|
||||
import { RoutesReceivedProvider
|
||||
, RoutesFilteredProvider
|
||||
, RoutesNotExportedProvider
|
||||
, RouteDetailsProvider
|
||||
}
|
||||
from 'app/context/routes';
|
||||
|
||||
@ -147,6 +148,7 @@ const RoutesPage = () => {
|
||||
return (
|
||||
<NeighborProvider neighborId={neighborId}>
|
||||
<RelatedNeighborsProvider>
|
||||
<RouteDetailsProvider>
|
||||
|
||||
<RoutesNotExportedProvider
|
||||
routeServerId={routeServerId}
|
||||
@ -171,45 +173,10 @@ const RoutesPage = () => {
|
||||
</RoutesFilteredProvider>
|
||||
</RoutesNotExportedProvider>
|
||||
|
||||
</RouteDetailsProvider>
|
||||
</RelatedNeighborsProvider>
|
||||
</NeighborProvider>
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
<BgpAttributesModal />
|
||||
<div className="row details-main">
|
||||
<div className="col-main col-lg-9 col-md-12">
|
||||
|
||||
<QuickLinks routes={this.props.routes} />
|
||||
|
||||
<RoutesViewEmpty routes={this.props.routes}
|
||||
hasQuery={!!this.props.filterValue}
|
||||
loadNotExported={this.props.loadNotExported} />
|
||||
<RoutesView
|
||||
type={ROUTES_FILTERED}
|
||||
routeserverId={this.props.params.routeserverId}
|
||||
protocolId={this.props.params.protocolId} />
|
||||
|
||||
{this.props.receivedLoading && <RoutesLoadingIndicator />}
|
||||
|
||||
<RoutesView
|
||||
type={ROUTES_RECEIVED}
|
||||
routeserverId={this.props.params.routeserverId}
|
||||
protocolId={this.props.params.protocolId} />
|
||||
|
||||
{this.props.notExportedLoading && <RoutesLoadingIndicator />}
|
||||
|
||||
<RoutesView
|
||||
type={ROUTES_NOT_EXPORTED}
|
||||
routeserverId={this.props.params.routeserverId}
|
||||
protocolId={this.props.params.protocolId} />
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
*/
|
||||
|
||||
export default RoutesPage;
|
||||
|
Loading…
x
Reference in New Issue
Block a user