summaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/apps/networkMapApp/src
diff options
context:
space:
mode:
authorAijana Schumann <aijana.schumann@highstreet-technologies.com>2020-08-31 15:23:24 +0200
committerAijana S <aijana.schumann@highstreet-technologies.com>2020-08-31 17:56:42 +0000
commit77a101dfcbad1e6a6a91d8bea9b0df8b7d8e76ff (patch)
tree7023c842a5844c1709b17b9284e915e10f740dad /sdnr/wt/odlux/apps/networkMapApp/src
parent0ccd5b341abc1ce0320151fd91263b0c25ca16f1 (diff)
Add searchbar to NetworkMap
Add a searchbar to the networkmap Issue-ID: CCSDK-2563 Signed-off-by: Aijana Schumann <aijana.schumann@highstreet-technologies.com> Change-Id: Ia607f9c517d3ec7ca7681243ad13c7dc5864c5ae
Diffstat (limited to 'sdnr/wt/odlux/apps/networkMapApp/src')
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/actions/searchAction.ts25
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map.tsx2
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/searchBar.tsx158
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/handlers/rootReducer.ts3
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/handlers/searchReducer.ts33
5 files changed, 221 insertions, 0 deletions
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/actions/searchAction.ts b/sdnr/wt/odlux/apps/networkMapApp/src/actions/searchAction.ts
new file mode 100644
index 000000000..a553319da
--- /dev/null
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/actions/searchAction.ts
@@ -0,0 +1,25 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { Action } from '../../../../framework/src/flux/action';
+
+export class SetSearchValueAction extends Action{
+ constructor(public value: string){
+ super();
+ }
+}
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map.tsx
index 1aabb92c6..d9075c889 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/map.tsx
@@ -39,6 +39,7 @@ import apartment from '../../icons/apartment.png';
import datacenter from '../../icons/datacenter.png';
import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect';
+import SearchBar from './searchBar';
import { verifyResponse, IsTileServerReachableAction, handleConnectionError } from '../actions/connectivityAction';
import ConnectionInfo from './connectionInfo'
import { ApplicationStore } from '../../../../framework/src/store/applicationStore';
@@ -561,6 +562,7 @@ class Map extends React.Component<mapProps, { isPopupOpen: boolean }> {
this.state.isPopupOpen &&
<MapPopup onClose={() => { this.setState({ isPopupOpen: false }); }} />
}
+ <SearchBar />
<ConnectionInfo />
</div>
</>
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/searchBar.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/searchBar.tsx
new file mode 100644
index 000000000..0c7607bb7
--- /dev/null
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/searchBar.tsx
@@ -0,0 +1,158 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import * as React from 'react';
+import { makeStyles, Paper, InputBase, IconButton, Divider, Popover, Typography } from '@material-ui/core';
+import SearchIcon from '@material-ui/icons/Search';
+
+import { URL_API } from '../config';
+import { isSite } from '../utils/utils';
+import { site } from '../model/site';
+import { link } from '../model/link';
+import { SelectSiteAction, SelectLinkAction } from '../actions/detailsAction';
+import { HighlightLinkAction, HighlightSiteAction, ZoomToSearchResultAction } from '../actions/mapActions';
+import { calculateMidPoint } from '../utils/mapUtils';
+import { SetSearchValueAction } from '../actions/searchAction';
+import connect,{ Connect, IDispatcher } from '../../../../framework/src/flux/connect';
+import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
+
+
+
+
+
+
+const styles = makeStyles({
+ root: {
+ //{ padding:5, position: 'absolute', display:'flex', flexDirection:"column",top: 150, width: 200}
+ padding: '2px 4px',
+ position: 'absolute',
+ display:'flex',
+ alignItems: 'center',
+ top: 15,
+ marginLeft: 5,
+ width: 400,
+ },
+ input: {
+ flex: 1,
+ marginLeft: 5
+ },
+ iconButton: {
+ padding: 10,
+ },
+ divider: {
+ height: 28,
+ margin: 4,
+ },
+ });
+
+
+const SearchBar: React.FunctionComponent<searchBarProps> = (props) =>{
+
+ const classes = styles();
+ const [anchorEl, setAnchorEl] = React.useState<any>(null);
+ const [errorMessage, setErrorMessage] = React.useState("");
+
+ const divRef = React.useRef();
+
+ const handleClick = (e: any) =>{
+
+ setAnchorEl(null);
+ if(props.searchterm.length>0){
+
+ const siteResult = fetch(`${URL_API}/site/${props.searchterm}`)
+
+ const linkResult = fetch(`${URL_API}/link/${props.searchterm}`);
+
+ Promise.all([ siteResult, linkResult]).then((result)=>{
+ const suceededResults = result.filter(el=> el!==undefined);
+
+ if(suceededResults.length==0){
+ setAnchorEl(divRef.current);
+ setErrorMessage("No element found.")
+
+ }else{
+ suceededResults[0].json().then(result =>{
+ if(isSite(result)){
+ props.selectSite(result);
+ props.highlightSite(result);
+ props.zoomToSearchResult(result.geoLocation.lat, result.geoLocation.lon);
+ }else{
+ props.selectLink(result);
+ props.highlightLink(result);
+ const midPoint = calculateMidPoint(result.locationA.lat, result.locationA.lon, result.locationB.lat, result.locationB.lon);
+ props.zoomToSearchResult(midPoint[1], midPoint[0])
+ }
+ });
+ }
+ });
+ }
+ e.preventDefault();
+}
+
+ const open = Boolean(anchorEl);
+
+ const reachabe = props.isTopoServerReachable && props.isTileServerReachable;
+
+ return (
+ <>
+ <Paper ref={divRef} component="form" className={classes.root}>
+ <InputBase
+ disabled={!reachabe}
+ className={classes.input}
+ placeholder="Find sites or links by name"
+ inputProps={{ 'aria-label': 'search sites or links' }}
+ value={props.searchterm}
+ onChange={e=> props.setSearchTerm(e.currentTarget.value)}
+ />
+ <Divider className={classes.divider} orientation="vertical" />
+ <IconButton type="submit" className={classes.iconButton} aria-label="search" onClick={handleClick}>
+ <SearchIcon />
+ </IconButton>
+ </Paper>
+ <Popover open={open} onClose={e=> setAnchorEl(null)} anchorEl={anchorEl} anchorOrigin={{
+ vertical: "bottom",
+ horizontal: "left"
+ }}>
+ <Paper style={{width: 380, padding:10}}>
+ <Typography variant="body1">{errorMessage}</Typography>
+ </Paper>
+ </Popover>
+ </>
+ );
+}
+
+const mapStateToProps = (state: IApplicationStoreState) => ({
+ searchterm: state.network.search.value,
+ isTopoServerReachable: state.network.connectivity.isToplogyServerAvailable,
+ isTileServerReachable: state.network.connectivity.isTileServerAvailable
+
+});
+
+type searchBarProps = Connect<typeof mapStateToProps, typeof mapDispatchToProps>;
+
+
+const mapDispatchToProps = (dispatcher: IDispatcher) => ({
+ selectSite:(site: site)=> dispatcher.dispatch(new SelectSiteAction(site)),
+ selectLink:(link: link) => dispatcher.dispatch(new SelectLinkAction(link)),
+ highlightLink:(link: link)=> dispatcher.dispatch(new HighlightLinkAction(link)),
+ highlightSite: (site: site) => dispatcher.dispatch(new HighlightSiteAction(site)),
+ setSearchTerm: (value: string) => dispatcher.dispatch(new SetSearchValueAction(value)),
+ zoomToSearchResult: (lat: number, lon: number) => dispatcher.dispatch(new ZoomToSearchResultAction(lat, lon)),
+});;
+
+export default (connect(mapStateToProps,mapDispatchToProps)(SearchBar)) \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/handlers/rootReducer.ts b/sdnr/wt/odlux/apps/networkMapApp/src/handlers/rootReducer.ts
index 4069ed24d..c9c475411 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/handlers/rootReducer.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/handlers/rootReducer.ts
@@ -21,12 +21,14 @@ import { combineActionHandler } from '../../../../framework/src/flux/middleware'
import { DetailsReducer, DetailsStoreState } from "./detailsReducer";
import { PopupsReducer, popupStoreState } from "./popupReducer";
import { MapReducer, mapState } from "./mapReducer";
+import { SearchReducer, searchState } from "./searchReducer";
import { connectivityState, ConnectivityReducer } from './connectivityReducer';
export interface INetworkAppStoreState{
details: DetailsStoreState,
popup: popupStoreState,
map: mapState,
+ search: searchState,
connectivity: connectivityState
}
@@ -40,6 +42,7 @@ const appHandler = {
details: DetailsReducer,
popup: PopupsReducer,
map: MapReducer,
+ search: SearchReducer,
connectivity: ConnectivityReducer};
export const networkmapRootHandler = combineActionHandler<INetworkAppStoreState>(appHandler)
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/handlers/searchReducer.ts b/sdnr/wt/odlux/apps/networkMapApp/src/handlers/searchReducer.ts
new file mode 100644
index 000000000..68aade477
--- /dev/null
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/handlers/searchReducer.ts
@@ -0,0 +1,33 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ */
+
+import { IActionHandler } from '../../../../framework/src/flux/action';
+import { SetSearchValueAction } from "../actions/searchAction";
+
+export type searchState = {value: string};
+
+const initialState: searchState = {value: ''};
+
+export const SearchReducer: IActionHandler<searchState> =(state=initialState, action)=> {
+
+ if(action instanceof SetSearchValueAction){
+ state = Object.assign({}, state, { value: action.value });
+ }
+
+ return state;
+} \ No newline at end of file