|
|
@ -15,7 +15,7 @@ import "react-loader-spinner/dist/loader/css/react-spinner-loader.css"; |
|
|
|
import { ToastContainer, toast } from "react-toastify"; |
|
|
|
import { ToastContainer, toast } from "react-toastify"; |
|
|
|
import "react-toastify/dist/ReactToastify.css"; |
|
|
|
import "react-toastify/dist/ReactToastify.css"; |
|
|
|
import './MapMonitoring.css'; |
|
|
|
import './MapMonitoring.css'; |
|
|
|
import { BASE_SIMPRO_LUMEN_IMAGE } from '../../const/ApiConst'; |
|
|
|
import { BASE_SIMPRO_LUMEN_IMAGE, PROYEK_SEARCH } from '../../const/ApiConst'; |
|
|
|
import DEFAULT_USER_ICON from '../../assets/img/avatars/user.png'; |
|
|
|
import DEFAULT_USER_ICON from '../../assets/img/avatars/user.png'; |
|
|
|
import pinRouteStart from '../../assets/img/map/pin_route_green.png'; |
|
|
|
import pinRouteStart from '../../assets/img/map/pin_route_green.png'; |
|
|
|
import pinRouteEnd from '../../assets/img/map/pin_route_red.png'; |
|
|
|
import pinRouteEnd from '../../assets/img/map/pin_route_red.png'; |
|
|
@ -26,13 +26,32 @@ import 'leaflet.markercluster/dist/leaflet.markercluster.js' |
|
|
|
import 'leaflet-control-geocoder/dist/Control.Geocoder.css' |
|
|
|
import 'leaflet-control-geocoder/dist/Control.Geocoder.css' |
|
|
|
import 'leaflet-control-geocoder/dist/Control.Geocoder.js' |
|
|
|
import 'leaflet-control-geocoder/dist/Control.Geocoder.js' |
|
|
|
import moment from 'moment'; |
|
|
|
import moment from 'moment'; |
|
|
|
|
|
|
|
import axios from "../../const/interceptorApi"; |
|
|
|
|
|
|
|
const MapMonitoring = ({ ...props }) => { |
|
|
|
|
|
|
|
let role_id = '', user_id = '', proyek_id = '', isLogin = '', token = ''; |
|
|
|
|
|
|
|
if (props.location.state && props.location.state.role_id && props.location.state.user_id) { |
|
|
|
|
|
|
|
role_id = props.location.state.role_id; |
|
|
|
|
|
|
|
user_id = props.location.state.user_id; |
|
|
|
|
|
|
|
token = props.location.state.token; |
|
|
|
|
|
|
|
isLogin = props.location.state.isLogin; |
|
|
|
|
|
|
|
|
|
|
|
const MapMonitoring = () => { |
|
|
|
} else { |
|
|
|
|
|
|
|
role_id = localStorage.getItem("role_id"); |
|
|
|
|
|
|
|
proyek_id = localStorage.getItem("proyek_id"); |
|
|
|
|
|
|
|
user_id = localStorage.getItem("user_id"); |
|
|
|
|
|
|
|
token = localStorage.getItem("token"); |
|
|
|
|
|
|
|
isLogin = localStorage.getItem("isLogin"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const HEADER = { |
|
|
|
|
|
|
|
headers: { |
|
|
|
|
|
|
|
"Content-Type": "application/json", |
|
|
|
|
|
|
|
Authorization: `Bearer ${token}`, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}; |
|
|
|
const GRID_LEFT = 6; |
|
|
|
const GRID_LEFT = 6; |
|
|
|
const GRID_MIDDLE = 12; |
|
|
|
const GRID_MIDDLE = 12; |
|
|
|
const GRID_RIGHT = 6; |
|
|
|
const GRID_RIGHT = 6; |
|
|
|
const GRID_TOTAL = GRID_LEFT+GRID_MIDDLE+GRID_RIGHT;
|
|
|
|
const GRID_TOTAL = GRID_LEFT + GRID_MIDDLE + GRID_RIGHT; |
|
|
|
const mapRef = useRef() |
|
|
|
const mapRef = useRef() |
|
|
|
const center = { |
|
|
|
const center = { |
|
|
|
// lat: -6.200000,
|
|
|
|
// lat: -6.200000,
|
|
|
@ -41,7 +60,7 @@ const MapMonitoring = () => { |
|
|
|
lng: 120.13025155062624 |
|
|
|
lng: 120.13025155062624 |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
const {userPoints, mymap, openLeft, openRight, routingBarVisible, userHistory, isSearchingRoute, selectedFeature} = useSelector(state => state.mapReducer); |
|
|
|
const { userPoints, mymap, openLeft, openRight, routingBarVisible, userHistory, isSearchingRoute, selectedFeature } = useSelector(state => state.mapReducer); |
|
|
|
const [gridMiddle, setGridMiddle] = useState(GRID_MIDDLE); |
|
|
|
const [gridMiddle, setGridMiddle] = useState(GRID_MIDDLE); |
|
|
|
const [gridLeft, setGridLeft] = useState(0); |
|
|
|
const [gridLeft, setGridLeft] = useState(0); |
|
|
|
const [gridRight, setGridRight] = useState(0); |
|
|
|
const [gridRight, setGridRight] = useState(0); |
|
|
@ -88,45 +107,45 @@ const MapMonitoring = () => { |
|
|
|
var startIcon = new L.Icon({ |
|
|
|
var startIcon = new L.Icon({ |
|
|
|
iconSize: [60, 60], |
|
|
|
iconSize: [60, 60], |
|
|
|
iconAnchor: [30, 47], |
|
|
|
iconAnchor: [30, 47], |
|
|
|
popupAnchor: [1, -24], |
|
|
|
popupAnchor: [1, -24], |
|
|
|
iconUrl: pinRouteStart |
|
|
|
iconUrl: pinRouteStart |
|
|
|
}); |
|
|
|
}); |
|
|
|
var endIcon = new L.Icon({ |
|
|
|
var endIcon = new L.Icon({ |
|
|
|
iconSize: [60, 60], |
|
|
|
iconSize: [60, 60], |
|
|
|
iconAnchor: [30, 47], |
|
|
|
iconAnchor: [30, 47], |
|
|
|
popupAnchor: [1, -24], |
|
|
|
popupAnchor: [1, -24], |
|
|
|
iconUrl: pinRouteEnd |
|
|
|
iconUrl: pinRouteEnd |
|
|
|
}); |
|
|
|
}); |
|
|
|
var onTripIcon = new L.Icon({ |
|
|
|
var onTripIcon = new L.Icon({ |
|
|
|
iconSize: [60, 60], |
|
|
|
iconSize: [60, 60], |
|
|
|
iconAnchor: [30, 47], |
|
|
|
iconAnchor: [30, 47], |
|
|
|
popupAnchor: [1, -24], |
|
|
|
popupAnchor: [1, -24], |
|
|
|
iconUrl: pinRouteOnTrip |
|
|
|
iconUrl: pinRouteOnTrip |
|
|
|
}); |
|
|
|
}); |
|
|
|
let userHistoryLayer = L.geoJson(userHistory, { |
|
|
|
let userHistoryLayer = L.geoJson(userHistory, { |
|
|
|
name: 'userHistoryLayer', |
|
|
|
name: 'userHistoryLayer', |
|
|
|
onEachFeature: function(feature, layer) { |
|
|
|
onEachFeature: function (feature, layer) { |
|
|
|
var popupText = `<b>Status: </b>${feature.properties.type}<br>
|
|
|
|
var popupText = `<b>Status: </b>${feature.properties.type}<br>
|
|
|
|
<b>Time: </b> ${feature.properties.wptime ? moment(feature.properties.wptime).format("DD-MM-YYYY HH:mm:ss") : '-'}`; |
|
|
|
<b>Time: </b> ${feature.properties.wptime ? moment(feature.properties.wptime).format("DD-MM-YYYY HH:mm:ss") : '-'}`; |
|
|
|
|
|
|
|
|
|
|
|
layer.bindPopup(popupText, { |
|
|
|
layer.bindPopup(popupText, { |
|
|
|
closeButton: true, |
|
|
|
closeButton: true, |
|
|
|
// offset: L.point(0, -20)
|
|
|
|
// offset: L.point(0, -20)
|
|
|
|
}); |
|
|
|
}); |
|
|
|
layer.on('click', function() { |
|
|
|
layer.on('click', function () { |
|
|
|
layer.openPopup(); |
|
|
|
layer.openPopup(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}, |
|
|
|
}, |
|
|
|
pointToLayer: function(feature, latlng) { |
|
|
|
pointToLayer: function (feature, latlng) { |
|
|
|
var type = feature.properties.type; |
|
|
|
var type = feature.properties.type; |
|
|
|
if (type === 'Start') { |
|
|
|
if (type === 'Start') { |
|
|
|
return L.marker(latlng, {icon: startIcon}); |
|
|
|
return L.marker(latlng, { icon: startIcon }); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (type === "Working") { |
|
|
|
else if (type === "Working") { |
|
|
|
return L.marker(latlng, {icon: onTripIcon}); |
|
|
|
return L.marker(latlng, { icon: onTripIcon }); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (type === "End") { |
|
|
|
else if (type === "End") { |
|
|
|
return L.marker(latlng, {icon: endIcon}); |
|
|
|
return L.marker(latlng, { icon: endIcon }); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
}); |
|
|
|
}); |
|
|
@ -155,9 +174,11 @@ const MapMonitoring = () => { |
|
|
|
// init for left content panel, get projects and build tree select antd
|
|
|
|
// init for left content panel, get projects and build tree select antd
|
|
|
|
const getMapLeftContent = async () => { |
|
|
|
const getMapLeftContent = async () => { |
|
|
|
store.dispatch(setMapLoading(true)); |
|
|
|
store.dispatch(setMapLoading(true)); |
|
|
|
let project = await ApiProject.list(); |
|
|
|
|
|
|
|
// console.log('project', project);
|
|
|
|
let project = await ApiProject.search(role_id); |
|
|
|
if (project && project.status && project.data && project.data.length > 0) { |
|
|
|
// console.log('projectsearch', projectsearch.data.data);
|
|
|
|
|
|
|
|
console.log('project', project); |
|
|
|
|
|
|
|
if (project && project.data && project.data.length > 0) { |
|
|
|
let projectData = [ |
|
|
|
let projectData = [ |
|
|
|
{ |
|
|
|
{ |
|
|
|
"title": 'All', |
|
|
|
"title": 'All', |
|
|
@ -182,13 +203,13 @@ const MapMonitoring = () => { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const onEachFeatureUserPoints = (feature, layer) => { |
|
|
|
const onEachFeatureUserPoints = (feature, layer) => { |
|
|
|
layer.on('click', function(e) { |
|
|
|
layer.on('click', function (e) { |
|
|
|
L.DomEvent.stopPropagation(e); |
|
|
|
L.DomEvent.stopPropagation(e); |
|
|
|
if (!store.getState().mapReducer.routingBarVisible) { |
|
|
|
if (!store.getState().mapReducer.routingBarVisible) { |
|
|
|
// proceed only when routing mode is not visible
|
|
|
|
// proceed only when routing mode is not visible
|
|
|
|
showHighLight(feature, e); |
|
|
|
showHighLight(feature, e); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const renderClassMarker = (feature) => { |
|
|
|
const renderClassMarker = (feature) => { |
|
|
@ -226,7 +247,7 @@ const MapMonitoring = () => { |
|
|
|
let lon = feature.geometry.coordinates[0]; |
|
|
|
let lon = feature.geometry.coordinates[0]; |
|
|
|
|
|
|
|
|
|
|
|
// create a new marker using the icon style
|
|
|
|
// create a new marker using the icon style
|
|
|
|
let marker = new L.Marker([lat,lon],{icon: logoMarker}); |
|
|
|
let marker = new L.Marker([lat, lon], { icon: logoMarker }); |
|
|
|
markerCluster.addLayer(marker); |
|
|
|
markerCluster.addLayer(marker); |
|
|
|
return marker; |
|
|
|
return marker; |
|
|
|
} |
|
|
|
} |
|
|
@ -234,7 +255,7 @@ const MapMonitoring = () => { |
|
|
|
function showHighLight(feature, e) { |
|
|
|
function showHighLight(feature, e) { |
|
|
|
// console.log('showHighLight feature', feature);
|
|
|
|
// console.log('showHighLight feature', feature);
|
|
|
|
// console.log('showHighLight e', e);
|
|
|
|
// console.log('showHighLight e', e);
|
|
|
|
removeLayerByName('popupTemp'); |
|
|
|
removeLayerByName('popupTemp'); |
|
|
|
|
|
|
|
|
|
|
|
// let selectedIcon = e.target.options.icon;
|
|
|
|
// let selectedIcon = e.target.options.icon;
|
|
|
|
// let classIcon = e.target.options.icon.options.className;
|
|
|
|
// let classIcon = e.target.options.icon.options.className;
|
|
|
@ -256,7 +277,7 @@ const MapMonitoring = () => { |
|
|
|
// popupAnchor: [0, -80]
|
|
|
|
// popupAnchor: [0, -80]
|
|
|
|
// });
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
// add highlight
|
|
|
|
// add highlight
|
|
|
|
// console.log('selectedIcon', selectedIcon);
|
|
|
|
// console.log('selectedIcon', selectedIcon);
|
|
|
|
// console.log('classList', e.target.options.icon.options.classList);
|
|
|
|
// console.log('classList', e.target.options.icon.options.classList);
|
|
|
|
// if (!openRight) {
|
|
|
|
// if (!openRight) {
|
|
|
@ -271,8 +292,8 @@ const MapMonitoring = () => { |
|
|
|
// kalo bukan point bikin hightlight jadi biru
|
|
|
|
// kalo bukan point bikin hightlight jadi biru
|
|
|
|
if (feature && feature.geometry && feature.geometry.type !== 'Point') { |
|
|
|
if (feature && feature.geometry && feature.geometry.type !== 'Point') { |
|
|
|
L.geoJSON(feature, { |
|
|
|
L.geoJSON(feature, { |
|
|
|
style: function(feature) { |
|
|
|
style: function (feature) { |
|
|
|
return {color: 'blue'} |
|
|
|
return { color: 'blue' } |
|
|
|
}, |
|
|
|
}, |
|
|
|
name: 'popupTemp', |
|
|
|
name: 'popupTemp', |
|
|
|
onEachFeature: function (feature, layer) { |
|
|
|
onEachFeature: function (feature, layer) { |
|
|
@ -287,7 +308,7 @@ const MapMonitoring = () => { |
|
|
|
// opening right panel
|
|
|
|
// opening right panel
|
|
|
|
store.dispatch(setOpenRight(!openRight)); |
|
|
|
store.dispatch(setOpenRight(!openRight)); |
|
|
|
store.dispatch(setSelectedFeature(feature)); |
|
|
|
store.dispatch(setSelectedFeature(feature)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const MapContent = useMemo(() => { |
|
|
|
const MapContent = useMemo(() => { |
|
|
|
return ( |
|
|
|
return ( |
|
|
@ -299,20 +320,20 @@ const MapMonitoring = () => { |
|
|
|
<div id="map-area" style={{ height: '90vh', width: '100%' }} ref={mapRef}></div> |
|
|
|
<div id="map-area" style={{ height: '90vh', width: '100%' }} ref={mapRef}></div> |
|
|
|
<button |
|
|
|
<button |
|
|
|
title='Project List' |
|
|
|
title='Project List' |
|
|
|
style={{position: 'absolute', top: 80, left: 10, zIndex: 999, backgroundColor:'white', backgroundSize:'34px 34px', width: '34px', height: '34px', borderRadius: '2px', borderWidth: '1px', borderColor: 'grey'}}
|
|
|
|
style={{ position: 'absolute', top: 80, left: 10, zIndex: 999, backgroundColor: 'white', backgroundSize: '34px 34px', width: '34px', height: '34px', borderRadius: '2px', borderWidth: '1px', borderColor: 'grey' }} |
|
|
|
onClick={() => store.dispatch(setOpenLeft(!openLeft))}> |
|
|
|
onClick={() => store.dispatch(setOpenLeft(!openLeft))}> |
|
|
|
<i className='fa fa-list'></i> |
|
|
|
<i className='fa fa-list'></i> |
|
|
|
</button> |
|
|
|
</button> |
|
|
|
{ routingBarVisible && <RoutingBar /> } |
|
|
|
{routingBarVisible && <RoutingBar />} |
|
|
|
{ isSearchingRoute && ( |
|
|
|
{isSearchingRoute && ( |
|
|
|
<div className="loader-container"> |
|
|
|
<div className="loader-container"> |
|
|
|
<Loader |
|
|
|
<Loader |
|
|
|
type="TailSpin" |
|
|
|
type="TailSpin" |
|
|
|
color="#36D7B7" |
|
|
|
color="#36D7B7" |
|
|
|
height={100} |
|
|
|
height={100} |
|
|
|
width={100} |
|
|
|
width={100} |
|
|
|
/> |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
)} |
|
|
|
)} |
|
|
|
</Col> |
|
|
|
</Col> |
|
|
|
<Col span={gridRight}> |
|
|
|
<Col span={gridRight}> |
|
|
@ -321,13 +342,13 @@ const MapMonitoring = () => { |
|
|
|
<ToastContainer autoClose={5000} /> |
|
|
|
<ToastContainer autoClose={5000} /> |
|
|
|
</Row> |
|
|
|
</Row> |
|
|
|
) |
|
|
|
) |
|
|
|
}, [openLeft, openRight, gridLeft, gridMiddle, gridRight, routingBarVisible ]) |
|
|
|
}, [openLeft, openRight, gridLeft, gridMiddle, gridRight, routingBarVisible]) |
|
|
|
|
|
|
|
|
|
|
|
const renderGridMap = () => { |
|
|
|
const renderGridMap = () => { |
|
|
|
let middle = GRID_MIDDLE; |
|
|
|
let middle = GRID_MIDDLE; |
|
|
|
let left = GRID_LEFT; |
|
|
|
let left = GRID_LEFT; |
|
|
|
let right = GRID_RIGHT; |
|
|
|
let right = GRID_RIGHT; |
|
|
|
if (openLeft && openRight){ |
|
|
|
if (openLeft && openRight) { |
|
|
|
middle = GRID_MIDDLE; |
|
|
|
middle = GRID_MIDDLE; |
|
|
|
left = GRID_LEFT; |
|
|
|
left = GRID_LEFT; |
|
|
|
right = GRID_RIGHT; |
|
|
|
right = GRID_RIGHT; |
|
|
|