Skip to content

Commit 6c9800b

Browse files
author
riteshsangwan
committed
list rtfzs and toggle show/hide each rtfz
1 parent cbd6177 commit 6c9800b

File tree

12 files changed

+196
-30
lines changed

12 files changed

+196
-30
lines changed

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
GOOGLE_API_KEY=AIzaSyCrL-O319wNJK8kk8J_JAYsWgu6yo5YsDI
2-
REACT_APP_API_BASE_PATH=https://kb-dsp-server-dev.herokuapp.com
2+
REACT_APP_API_BASE_PATH=http://localhost:3500
33
REACT_APP_AUTH0_CLIENT_ID=3CGKzjS2nVSqHxHHE64RhvvKY6e0TYpK
44
REACT_APP_AUTH0_CLIENT_DOMAIN=dronetest.auth0.com
5-
REACT_APP_SOCKET_URL=https://kb-dsp-server-dev.herokuapp.com
5+
REACT_APP_SOCKET_URL=http://localhost:3500

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
"react-table": "^3.1.4",
9595
"react-tabs": "^0.8.2",
9696
"react-timeago": "^3.1.3",
97+
"react-toggle-button": "^2.1.0",
9798
"reactable": "^0.14.1",
9899
"redbox-react": "^1.2.10",
99100
"redux": "^3.0.0",

src/routes/MissionPlanner/components/MissionMap/MissionMap.jsx

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import CSSModules from 'react-css-modules';
33
import {withGoogleMap, GoogleMap, Marker, Polyline} from 'react-google-maps';
44
import _ from 'lodash';
55
import NoFlyZone from 'components/NoFlyZone';
6+
import Rtfz from '../Rtfz';
67
import {GOOGLE_MAPS_BOUNDS_TIMEOUT} from 'Const';
78
import styles from './MissionMap.scss';
89

@@ -32,19 +33,27 @@ export const MissionGoogleMap = withGoogleMap((props) => (
3233
{... mapConfig}
3334
onBoundsChanged={props.onBoundsChanged}
3435
ref={props.onMapLoad}
36+
options={{
37+
mapTypeControl: true,
38+
mapTypeControlOptions: {
39+
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
40+
position: google.maps.ControlPosition.TOP_CENTER,
41+
},
42+
}}
3543
onClick={props.onMapClick}
3644
>
3745
{props.markers.map((marker, index) => (
3846
<Marker key={index} {...marker} onDrag={(event) => props.onMarkerDrag(event, index)} />
3947
))}
40-
<Polyline {...polylineConfig} path={props.lineMarkerPosistions} />
48+
<Polyline {...polylineConfig} path={props.lineMarkerPositions} />
4149
{props.noFlyZones.map((zone) => <NoFlyZone key={zone.id} zone={zone} />)}
50+
{props.rtfzs.filter((single) => single.show === true).map((rtfz) => <Rtfz key={rtfz._id} zone={rtfz} />)}
4251
</GoogleMap>
4352
));
4453

4554
MissionGoogleMap.propTypes = {
4655
markers: PropTypes.array,
47-
lineMarkerPosistions: PropTypes.array,
56+
lineMarkerPositions: PropTypes.array,
4857
onMapLoad: PropTypes.func,
4958
onMapClick: PropTypes.func,
5059
onMarkerDrag: PropTypes.func,
@@ -62,13 +71,13 @@ export class MissionMap extends Component {
6271
this.handleMapLoad = this.handleMapLoad.bind(this);
6372

6473
this.state = {
65-
lineMarkerPosistions: getLineMarkerPositions(props.markers),
74+
lineMarkerPositions: getLineMarkerPositions(props.markers),
6675
};
6776
}
6877

6978
componentWillReceiveProps(nextProps) {
7079
this.setState({
71-
lineMarkerPosistions: getLineMarkerPositions(nextProps.markers),
80+
lineMarkerPositions: getLineMarkerPositions(nextProps.markers),
7281
});
7382
}
7483

@@ -86,22 +95,22 @@ export class MissionMap extends Component {
8695

8796
handleMapLoad(map) {
8897
this.map = map;
89-
if (map ) {
90-
if ( this.props.markers.length > 0 ) {
91-
this.fitMapToBounds(map, this.props.markers);
92-
} else {
93-
navigator.geolocation.getCurrentPosition((pos) => {
94-
map.panTo({
95-
lat: pos.coords.latitude,
96-
lng: pos.coords.longitude,
97-
});
98-
},
99-
null,
100-
{timeout: 60000}
101-
);
98+
if (map) {
99+
if (this.props.markers.length > 0) {
100+
this.fitMapToBounds(map, this.props.markers);
101+
} else {
102+
navigator.geolocation.getCurrentPosition((pos) => {
103+
map.panTo({
104+
lat: pos.coords.latitude,
105+
lng: pos.coords.longitude,
106+
});
107+
},
108+
null,
109+
{timeout: 60000}
110+
);
111+
}
102112
}
103113
}
104-
}
105114

106115
render() {
107116
return (
@@ -125,14 +134,15 @@ export class MissionMap extends Component {
125134
this.setState((prevState) => {
126135
const newState = _.cloneDeep(prevState);
127136

128-
newState.lineMarkerPosistions[index - 1] = event.latLng;
137+
newState.lineMarkerPositions[index - 1] = event.latLng;
129138

130139
return newState;
131140
});
132141
}
133142
}}
134-
lineMarkerPosistions={this.state.lineMarkerPosistions}
143+
lineMarkerPositions={this.state.lineMarkerPositions}
135144
noFlyZones={this.props.noFlyZones}
145+
rtfzs={this.props.rtfzs}
136146
/>
137147
</div>
138148
);
@@ -144,6 +154,7 @@ MissionMap.propTypes = {
144154
onMapClick: PropTypes.func,
145155
loadNfz: PropTypes.func.isRequired,
146156
noFlyZones: PropTypes.array.isRequired,
157+
rtfzs: PropTypes.array.isRequired,
147158
};
148159

149160
export default CSSModules(MissionMap, styles);

src/routes/MissionPlanner/components/MissionPlannerView.jsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, {PropTypes} from 'react';
22
import CSSModules from 'react-css-modules';
33
import MissionMap from './MissionMap';
44
import MissionSidebar from './MissionSidebar';
5+
import RTFZSidebar from './RTFZSidebar';
56
import MissionPlannerHeader from '../containers/MissionPlannerHeaderContainer';
67
import styles from './MissionPlannerView.scss';
78

@@ -12,9 +13,12 @@ const waypointIcon = getImage('icon-waypoint-blue.png');
1213

1314
export const getMissionItemsExt = (mission) => {
1415
let missionItemsExt = [];
15-
1616
mission.plannedHomePosition && missionItemsExt.push(mission.plannedHomePosition);
17-
missionItemsExt = [...missionItemsExt, ...mission.missionItems];
17+
18+
19+
if (mission.missionItems) {
20+
missionItemsExt = [...missionItemsExt, ...mission.missionItems];
21+
}
1822

1923
return missionItemsExt;
2024
};
@@ -64,7 +68,7 @@ export const getMarkerProps = (item, updateMissionItem) => {
6468
return markerProps;
6569
};
6670

67-
export const MissionPlannerView = ({mission, updateMissionItem, addMissionItem, deleteMissionItem, loadNfz, noFlyZones}) => {
71+
export const MissionPlannerView = ({mission, toggleRtfzHandler, updateMissionItem, addMissionItem, deleteMissionItem, loadNfz, noFlyZones}) => {
6872
const missionItemsExt = getMissionItemsExt(mission);
6973
const markersExt = missionItemsExt.map((item) => getMarkerProps(item, updateMissionItem));
7074

@@ -78,9 +82,11 @@ export const MissionPlannerView = ({mission, updateMissionItem, addMissionItem,
7882
loadNfz={loadNfz}
7983
noFlyZones={noFlyZones}
8084
markers={markersExt}
85+
rtfzs={mission.zones}
8186
onMapClick={(event) => addMissionItem({lat: event.latLng.lat(), lng: event.latLng.lng()})}
8287
/>
8388
<MissionSidebar missionItems={missionItemsExt} onUpdate={updateMissionItem} onDelete={deleteMissionItem} />
89+
<RTFZSidebar rtfzs={mission.zones} toggleRtfzHandler={toggleRtfzHandler} />
8490
</div>
8591
</div>
8692
);
@@ -93,6 +99,7 @@ MissionPlannerView.propTypes = {
9399
deleteMissionItem: PropTypes.func.isRequired,
94100
loadNfz: PropTypes.func.isRequired,
95101
noFlyZones: PropTypes.array.isRequired,
102+
toggleRtfzHandler: PropTypes.func.isRequired,
96103
};
97104

98105
export default CSSModules(MissionPlannerView, styles);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React, {PropTypes} from 'react';
2+
import CSSModules from 'react-css-modules';
3+
import styles from './RTFZSidebar.scss';
4+
import {Grid, Row, Col} from 'react-flexbox-grid/lib/index';
5+
import ToggleButton from 'react-toggle-button';
6+
7+
class RTFZSidebar extends React.Component {
8+
9+
/**
10+
* Hide the rtfz
11+
* This will invoke the redux action
12+
*
13+
* @param {Object} value the boolean value
14+
* @param {Object} rtfz the rtfz to toggle
15+
*/
16+
toggleRtfz(value, rtfz) {
17+
this.props.toggleRtfzHandler({value, rtfz});
18+
}
19+
20+
render() {
21+
const {rtfzs} = this.props;
22+
return (
23+
<div styleName="rtfz-sidebar">
24+
{rtfzs && rtfzs.length > 0 ? (
25+
rtfzs.map((rtfz) => (
26+
<Grid key={rtfz._id} styleName="sidebar-item">
27+
<Row>
28+
<Col xs={6} md={6}>{rtfz.description}</Col>
29+
<Col xs={6} md={6}>
30+
<div styleName="toggle-wrapper">
31+
<ToggleButton
32+
value={rtfz.show}
33+
activeLabel="hide"
34+
inactiveLabel="show"
35+
onToggle={(value) => this.toggleRtfz(value, rtfz)}
36+
/>
37+
</div>
38+
</Col>
39+
</Row>
40+
</Grid>
41+
))
42+
) : (
43+
<div styleName="note">No region to flyzones defined</div>
44+
)}
45+
</div>
46+
);
47+
}
48+
}
49+
50+
RTFZSidebar.propTypes = {
51+
rtfzs: PropTypes.array.isRequired,
52+
toggleRtfzHandler: PropTypes.func.isRequired,
53+
};
54+
55+
export default CSSModules(RTFZSidebar, styles, {allowMultiple: true});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.rtfz-sidebar {
2+
background: rgba(0,0,0,.1);
3+
height: auto;
4+
min-height: 0;
5+
max-height: 100%;
6+
position: absolute;
7+
left: 0;
8+
overflow: auto;
9+
padding: 4px;
10+
top: 0;
11+
margin: 0;
12+
width: 300px;
13+
z-index: 1;
14+
}
15+
.note {
16+
color: #fff;
17+
padding: 10px 0;
18+
text-align: center;
19+
}
20+
.sidebar-item {
21+
border: 1px solid #cccccc;
22+
box-shadow: 0px 0px 2px 2px rgba(102,102,102,0.7);
23+
padding: 10px;
24+
margin: 5px 0;
25+
width: 290px;
26+
background: #ffffff;
27+
.toggle-wrapper {
28+
float: right;
29+
}
30+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import RTFZSidebar from './RTFZSidebar';
2+
3+
export default RTFZSidebar;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, {PropTypes} from 'react';
2+
import {Marker, Polygon} from 'react-google-maps';
3+
4+
// define the type of region to fly zones
5+
const types = {
6+
point: 'Point',
7+
polygon: 'Polygon',
8+
};
9+
10+
export const Rtfz = ({zone}) => {
11+
if (zone.location.type === types.point) {
12+
return (
13+
<Marker
14+
options={{
15+
clickable: false,
16+
crossOnDrag: false,
17+
}}
18+
position={{lat: zone.location.coordinates[1], lng: zone.location.coordinates[0]}}
19+
/>
20+
);
21+
}
22+
const polygonOptions = {...zone.style, clickable: false, geodesic: true};
23+
return (
24+
<Polygon
25+
options={polygonOptions}
26+
path={zone.location.coordinates[0].map((pair) => ({lng: pair[0], lat: pair[1]}))}
27+
/>
28+
);
29+
};
30+
31+
Rtfz.propTypes = {
32+
zone: PropTypes.object.isRequired,
33+
};
34+
35+
export default Rtfz;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Rtfz from './Rtfz';
2+
3+
export default Rtfz;

src/routes/MissionPlanner/modules/MissionPlanner.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {handleActions} from 'redux-actions';
1+
import {handleActions, createAction} from 'redux-actions';
22
import {push} from 'react-router-redux';
33
import _ from 'lodash';
44
import APIService from 'services/APIService';
@@ -15,6 +15,7 @@ export const ADD_MISSION_ITEM = 'MissionPlanner/ADD_MISSION_ITEM';
1515
export const DELETE_MISSION_ITEM = 'MissionPlanner/DELETE_MISSION_ITEM';
1616
export const CLEAR_MISSION = 'MissionPlanner/CLEAR_MISSION';
1717
export const UPDATE_MISSION_NAME = 'MissionPlanner/UPDATE_MISSION_NAME';
18+
export const TOGGLE_RTFZ = 'MissionPlanner/TOGGLE_RTFZ';
1819

1920
// ------------------------------------
2021
// Actions
@@ -95,6 +96,8 @@ export const updateMissionName = (missionName) => async (dispatch) => {
9596
dispatch({type: UPDATE_MISSION_NAME, payload: {missionName}});
9697
};
9798

99+
const toggleRtfzHandler = createAction(TOGGLE_RTFZ);
100+
98101
export const actions = {
99102
load,
100103
save,
@@ -103,6 +106,7 @@ export const actions = {
103106
deleteMissionItem,
104107
clearMission,
105108
updateMissionName,
109+
toggleRtfzHandler,
106110
};
107111

108112
// ------------------------------------
@@ -113,7 +117,15 @@ export default handleActions({
113117
const newState = _.cloneDeep(state);
114118

115119
newState.mission = mission;
116-
120+
// if missionItems are not defined define them to empty array
121+
newState.mission.missionItems = newState.mission.missionItems || [];
122+
// add additional show property on each zone to individually show/hide zone
123+
if (mission.zones) {
124+
newState.mission.zones = mission.zones.map((single) => {
125+
single.show = true;
126+
return single;
127+
});
128+
}
117129
return newState;
118130
},
119131
[UPDATED]: (state, {payload: {mission}}) => {
@@ -214,6 +226,12 @@ export default handleActions({
214226

215227
return newState;
216228
},
229+
[TOGGLE_RTFZ]: (state, {payload: {value, rtfz}}) => {
230+
const newState = _.cloneDeep(state);
231+
const zone = _.filter(newState.mission.zones, {_id: rtfz._id})[0];
232+
zone.show = !value;
233+
return newState;
234+
},
217235
}, {
218236
mission: {
219237
id: '',

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy