diff options
Diffstat (limited to 'sdnr/wt/odlux/apps/networkMapApp/src/components/details')
3 files changed, 100 insertions, 40 deletions
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/details.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/details.tsx index 081276b5c..2540b20a7 100644 --- a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/details.tsx +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/details.tsx @@ -20,7 +20,7 @@ import * as React from 'react' import connect, { IDispatcher, Connect } from '../../../../../framework/src/flux/connect'; -import { site, Device } from '../../model/site'; +import { Site, Device } from '../../model/site'; import Typography from '@material-ui/core/Typography'; import { link } from '../../model/link'; import { Breadcrumbs, Link, Paper } from '@material-ui/core'; @@ -76,7 +76,7 @@ const Details: React.FunctionComponent<porps> = (props) => { }, [props.data]) const onLinkClick = async (id: string) => { - const result = await fetch(`${URL_API}/link/${id}`); + const result = await fetch(`${URL_API}/links/${id}`); if(result.ok){ const resultAsJson = await result.json(); const link = resultAsJson as link; @@ -102,10 +102,9 @@ const Details: React.FunctionComponent<porps> = (props) => { e.preventDefault(); } - const createDetailPanel = (data: site | link) => { - + const createDetailPanel = (data: Site | link) => { if (isSite(data)) { - return <SiteDetails navigate={props.navigateToApplication} updatedDevices={props.updatedDevices} loadDevices={props.loadDevices} site={data} onLinkClick={onLinkClick} /> + return <SiteDetails site={data} onLinkClick={onLinkClick} /> } else { return <LinkDetails link={data} /> } @@ -120,7 +119,7 @@ const Details: React.FunctionComponent<porps> = (props) => { const loadDetailsData = (id: string) =>{ - fetch(`${URL_API}/link/${id}`) + fetch(`${URL_API}/links/${id}`) .then(res => { if (res.ok) return res.json() @@ -135,7 +134,7 @@ const Details: React.FunctionComponent<porps> = (props) => { }) .catch(error => { - fetch(`${URL_API}/site/${id}`) + fetch(`${URL_API}/sites/name/${id}`) .then(res => { if (res.ok) return res.json() @@ -188,13 +187,13 @@ const mapStateToProps = (state: IApplicationStoreState) => ({ }); const mapDispatchToProps = (dispatcher: IDispatcher) => ({ - selectSite: (site: site) => dispatcher.dispatch(new SelectSiteAction(site)), + selectSite: (site: Site) => dispatcher.dispatch(new SelectSiteAction(site)), selectLink: (link: link) => dispatcher.dispatch(new SelectLinkAction(link)), clearDetails: () => dispatcher.dispatch(new ClearDetailsAction()), addHistory: (newEntry: HistoryEntry) => dispatcher.dispatch(new AddToHistoryAction(newEntry)), clearHistory: () => dispatcher.dispatch(new ClearHistoryAction()), highlightLink: (link: link) => dispatcher.dispatch(new HighlightLinkAction(link)), - highlightSite: (site: site) => dispatcher.dispatch(new HighlightSiteAction(site)), + highlightSite: (site: Site) => dispatcher.dispatch(new HighlightSiteAction(site)), loadDevices: async (networkElements: Device[]) => { await dispatcher.dispatch(CheckDeviceList(networkElements)) }, navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path, "test3")), undoMapSelection: () => dispatcher.dispatch(new RemoveHighlightingAction()) diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx index 81f9bba90..b2c724636 100644 --- a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx @@ -77,7 +77,7 @@ const LinkDetails: React.FunctionComponent<props> = (props) => { {name:"Site Name", val1: props.link.siteA, val2: props.link.siteB}, {name:"Latitude", val1: LatLonToDMS(props.link.locationA.lat), val2: LatLonToDMS(props.link.locationB.lat)}, {name:"Longitude", val1: LatLonToDMS(props.link.locationA.lon, true), val2: LatLonToDMS(props.link.locationB.lon, true)}, - {name:"Azimuth in °", val1: props.link.azimuthA.toFixed(2), val2: props.link.azimuthB.toFixed(2)} + props.link.azimuthA!= null && props.link.azimuthB != null && {name:"Azimuth in °", val1: props.link.azimuthA.toFixed(2), val2: props.link.azimuthB.toFixed(2)} ]; return (<div style={{ paddingLeft: "15px", paddingRight: "15px", paddingTop: "0px", display: 'flex', flexDirection: 'column' }}> diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx index 5e617be2d..3aa35c348 100644 --- a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx +++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx @@ -23,19 +23,28 @@ import { TextField, Tabs, Tab, Typography, AppBar, Button, Tooltip } from '@mate import MaterialTable, { ColumnModel, ColumnType, MaterialTableCtorType } from "../../../../../framework/src/components/material-table"; -import { site, Device } from '../../model/site'; +import { Site, Device, Address } from '../../model/site'; import DenseTable from '../denseTable'; import { LatLonToDMS } from '../../utils/mapUtils'; +import { CheckDeviceList, InitializeLoadedDevicesAction } from '../../actions/detailsAction'; +import { NavigateToApplication } from '../../../../../framework/src/actions/navigationActions'; +import connect, { Connect, IDispatcher } from '../../../../../framework/src/flux/connect'; +import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore'; -type minLinks = { name: string, azimuth: string} - -const FaultAlarmNotificationTable = MaterialTable as MaterialTableCtorType<minLinks>; +type linkRow = { name: string, azimuth?: string} +type deviceRow = { id: string;type: string,name: string,manufacturer: string,owner: string,status?: string,port: number[]} type panelId="links" | "nodes"; -type props = { site: site, updatedDevices: Device[]|null, navigate(applicationName: string, path?: string):void, onLinkClick(id: string): void, loadDevices(devices:Device[]): void }; +type siteDetailProps = { + site: Site, + onLinkClick(id: string): void, +} & props; + +type props = Connect<typeof mapStateToProps, typeof mapDispatchToProps>; + -const SiteDetails: React.FunctionComponent<props> = (props) => { +const SiteDetails: React.FunctionComponent<siteDetailProps> = (props) => { const [value, setValue] = React.useState<panelId>("links"); const [height, setHeight] = React.useState(330); @@ -59,21 +68,51 @@ const SiteDetails: React.FunctionComponent<props> = (props) => { // on update React.useEffect(()=>{ - - props.loadDevices(props.site.devices); + + if(props.site.devices!== null && props.site.devices.length>0){ + props.initializeDevices(props.site.devices); + props.loadDevices(props.site.devices); + } + handleResize(); - }, [props.site]) + }, [props.site]); const onHandleTabChange = (event: React.ChangeEvent<{}>, newValue: panelId) => { setValue(newValue); } - const linkRows: minLinks[] = props.site.links.map(link=> + //prepare link table + + let hasAzimuth = false; + const linkRows: linkRow[] = props.site.links.map(link=> { - return {name: link.name, azimuth: link.azimuthB.toFixed(2) } + if(link.azimuthB!==null){ + hasAzimuth=true; + return {name: link.name, azimuth: link.azimuthB.toFixed(2) } + + }else{ + return {name: link.name } + } + }); + + const linkTableHeader = hasAzimuth ? ["Link Name", "Azimuth in °"] : ["Link Name"]; + + //prepare device table + const deviceRows : deviceRow[] = props.updatedDevices.map(device=>{ + return{ + id: device.id, + name: device.name, + type: device.type, + status: device.status, + manufacturer: device.manufacturer, + owner: device.owner, + port: device.port + } + }); + const adressString = props.site.address == null ? null : buildAdress(props.site.address); return (<div style={{ padding: '15px', display: "flex", flexDirection:"column", minWidth:0, minHeight:0 }}> @@ -88,20 +127,20 @@ const SiteDetails: React.FunctionComponent<props> = (props) => { <TextField inputProps={{ 'aria-label': 'type' }} disabled={true} value={props.site.type} label="Type" style={{ marginTop: "5px" }} /> } { - props.site.address !== undefined && props.site.address.length > 0 && - <TextField inputProps={{ 'aria-label': 'adress' }} disabled={true} value={props.site.address} label="Adress" style={{ marginTop: "5px" }} /> + adressString !== null && + <TextField inputProps={{ 'aria-label': 'adress' }} disabled={true} value={adressString} label="Address" style={{ marginTop: "5px" }} /> } { - props.site.heighAGLInMeters !== undefined && props.site.heighAGLInMeters > 0 && - <TextField inputProps={{ 'aria-label': 'amsl-in-meters' }} disabled={true} value={props.site.heighAGLInMeters} label="AMSL in meters" style={{ marginTop: "5px" }} /> + props.site.heightAmslInMeters !== undefined && props.site.heightAmslInMeters > 0 && + <TextField inputProps={{ 'aria-label': 'amsl-in-meters' }} disabled={true} value={props.site.heightAmslInMeters} label="AMSL in meters" style={{ marginTop: "5px" }} /> } { - props.site.antennaHeightAGLInMeters !== undefined && props.site.antennaHeightAGLInMeters > 0 && - <TextField inputProps={{ 'aria-label': 'antenna-above-ground-in-meters' }} disabled={true} value={props.site.antennaHeightAGLInMeters} label="Atenna above ground in meters" style={{ marginTop: "5px" }} /> + props.site.antennaHeightAmslInMeters !== undefined && props.site.antennaHeightAmslInMeters > 0 && + <TextField inputProps={{ 'aria-label': 'antenna-above-ground-in-meters' }} disabled={true} value={props.site.antennaHeightAmslInMeters} label="Atenna above ground in meters" style={{ marginTop: "5px" }} /> } - <TextField inputProps={{ 'aria-label': 'latitude' }} style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.geoLocation.lat)} label="Latitude" /> - <TextField inputProps={{ 'aria-label': 'longitude' }} style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.geoLocation.lon, true)} label="Longitude" /> + <TextField inputProps={{ 'aria-label': 'latitude' }} style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.location.lat)} label="Latitude" /> + <TextField inputProps={{ 'aria-label': 'longitude' }} style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.location.lon, true)} label="Longitude" /> <AppBar position="static" style={{ marginTop: "5px", background: '#2E3B55' }}> <Tabs id="site-tabs" value={value} onChange={onHandleTabChange} aria-label="simple tabs example"> @@ -119,13 +158,8 @@ const SiteDetails: React.FunctionComponent<props> = (props) => { { props.site.links.length > 0 && - <DenseTable ariaLabelRow="available-links-table" ariaLabelColumn={["link-name", "azimuth"]} height={height} hover={true} headers={["Link Name", "Azimuth in °"]} data={linkRows} onClick={props.onLinkClick} ></DenseTable> - /** - * - * */ - - - } + <DenseTable ariaLabelRow="available-links-table" ariaLabelColumn={["link-name", "azimuth"]} height={height} hover={true} headers={linkTableHeader} data={linkRows} onClick={props.onLinkClick} ></DenseTable> + } </> @@ -134,19 +168,46 @@ const SiteDetails: React.FunctionComponent<props> = (props) => { value === "nodes" && <> { - props.site.devices.length === 0 && + props.site.devices === null && <Typography aria-label="no-nodes-avilable" variant="body1" style={{ marginTop: '10px' }}>No nodes available.</Typography> } { - props.site.devices.length>0 && props.updatedDevices !== null && - <DenseTable ariaLabelRow="available-nodes-table" ariaLabelColumn={["id","name","type", "manufacturer","owner","status", "ports", "actions"]} navigate={props.navigate} height={height} hover={false} headers={["ID","Name","Type", "Manufacturer","Owner","Status", "Ports", "Actions"]} actions={true} data={props.updatedDevices!} /> + props.site.devices?.length>0 && props.updatedDevices !== null && + <DenseTable ariaLabelRow="available-nodes-table" ariaLabelColumn={["id","name","type","status", "manufacturer","owner", "ports", "actions"]} navigate={props.navigateToApplication} height={height} hover={false} headers={["ID","Name","Type","Status", "Manufacturer","Owner", "Ports", "Actions"]} actions={true} data={deviceRows!} /> } </> } </div> ) +} + +const buildAdress = (adress: Address) =>{ + switch(adress.country){ + case "de": + return `${adress.streetAndNr}, ${adress.zipCode!== null? adress.zipCode : ''} ${adress.city}` + + case "us": + return `${adress.streetAndNr}, ${adress.city} ${adress.zipCode!== null? adress.zipCode : ''}` + + default: + console.log("address formatting for country {"+adress.country+"} not recognized, defaulting."); + return `${adress.streetAndNr}, ${adress.zipCode!== null? adress.zipCode : ''} ${adress.city}` + } + + } -export default SiteDetails;
\ No newline at end of file +const mapStateToProps = (state: IApplicationStoreState) => ({ + updatedDevices: state.network.details.checkedDevices +}); + +const mapDispatchToProps = (dispatcher: IDispatcher) => ({ + initializeDevices: (devices: Device[]) => {dispatcher.dispatch(new InitializeLoadedDevicesAction(devices))}, + loadDevices: async (networkElements: Device[]) => { await dispatcher.dispatch(CheckDeviceList(networkElements)) }, + navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path, "test3")), + +}) + +export default connect(mapStateToProps, mapDispatchToProps)(SiteDetails);
\ No newline at end of file |