Browse Source

add leaflet.markercluster and leaflet-control-geocoder

pull/2/head
ardhi 2 years ago
parent
commit
ee4575d4e8
  1. 2
      package.json
  2. 23
      src/appredux/modules/map/actions.js
  3. 8
      src/appredux/modules/map/reducers.js
  4. 6
      src/components/MapLeftContent/index.js
  5. 138
      src/components/MapRightContent/index.js
  6. 14
      src/services/api/base.js
  7. 71
      src/services/api/modules/map_monitoring/index.js
  8. 14
      src/utils/MapUtils.js
  9. 10
      src/views/MapMonitoring/MapMonitoring.css
  10. 79
      src/views/MapMonitoring/index.js

2
package.json

@ -50,7 +50,9 @@
"jspdf": "^2.5.1", "jspdf": "^2.5.1",
"jspdf-autotable": "^3.5.25", "jspdf-autotable": "^3.5.25",
"leaflet": "^1.8.0", "leaflet": "^1.8.0",
"leaflet-control-geocoder": "^2.4.0",
"leaflet-draw": "^1.0.4", "leaflet-draw": "^1.0.4",
"leaflet.markercluster": "^1.5.3",
"moment": "^2.24.0", "moment": "^2.24.0",
"node-sass": "^4.12.0", "node-sass": "^4.12.0",
"numeral": "^2.0.6", "numeral": "^2.0.6",

23
src/appredux/modules/map/actions.js

@ -13,6 +13,7 @@ export const SET_USER_POINTS = 'SET_USER_POINTS';
export const SET_SELECTED_FEATURE = 'SET_SELECTED_FEATURE'; export const SET_SELECTED_FEATURE = 'SET_SELECTED_FEATURE';
export const SET_ROUTINGBAR_VISIBLE = 'SET_ROUTINGBAR_VISIBLE'; export const SET_ROUTINGBAR_VISIBLE = 'SET_ROUTINGBAR_VISIBLE';
export const SET_IS_SEARCHING_ROUTE = 'SET_IS_SEARCHING_ROUTE'; export const SET_IS_SEARCHING_ROUTE = 'SET_IS_SEARCHING_ROUTE';
export const SET_SELECTED_PROJECT_IDS = 'SET_SELECTED_PROJECT_IDS';
export const setMymap = obj => dispatch => { export const setMymap = obj => dispatch => {
dispatch({ dispatch({
@ -84,6 +85,22 @@ export const setIsSearchingRoute = obj => dispatch => {
}) })
} }
export const setSelectedProjectIds = obj => dispatch => {
// filter to remove 'all' key
let projectIds = obj || [];
if (obj && obj.length > 0) {
let allIdx = obj.findIndex(n => n === 'all');
let pos = allIdx + 1;
if (allIdx > -1) {
projectIds = obj.slice(pos);
}
}
dispatch({
type: SET_SELECTED_PROJECT_IDS,
payload: projectIds
})
}
export const getUserPoints = async () => { export const getUserPoints = async () => {
@ -104,12 +121,14 @@ export const getUserPoints = async () => {
feature.properties = { feature.properties = {
"user_id": n.user_id, "user_id": n.user_id,
"Name": n.join_first_name ? n.join_first_name : '-', "Name": n.name ? n.name : '-',
"Clock in time": n.clock_in ? moment(n.clock_in).format('YYYY-MM-DD HH:mm:ss') : '-', "Clock in time": n.clock_in ? moment(n.clock_in).format('YYYY-MM-DD HH:mm:ss') : '-',
"Clock in location": n.clock_in_loc ? n.clock_in_loc : '-', "Clock in location": n.clock_in_loc ? n.clock_in_loc : '-',
"Clock out time": n.clock_out ? moment(n.clock_out).format('YYYY-MM-DD HH:mm:ss') : '-', "Clock out time": n.clock_out ? moment(n.clock_out).format('YYYY-MM-DD HH:mm:ss') : '-',
"Clock out location": n.clock_out_loc ? n.clock_out_loc : '-', "Clock out location": n.clock_out_loc ? n.clock_out_loc : '-',
"image": n.image_selfie ? n.image_selfie : '' // still dummy "image": n.image_selfie ? n.image_selfie : '',
"Projects": n.projects ? n.projects : null,
"presence_status": n.presence_status ? n.presence_status : null
} }
feature.geometry = { feature.geometry = {

8
src/appredux/modules/map/reducers.js

@ -8,7 +8,8 @@ import {
SET_OPEN_LEFT, SET_OPEN_LEFT,
SET_OPEN_RIGHT, SET_OPEN_RIGHT,
SET_ROUTINGBAR_VISIBLE, SET_ROUTINGBAR_VISIBLE,
SET_IS_SEARCHING_ROUTE SET_IS_SEARCHING_ROUTE,
SET_SELECTED_PROJECT_IDS
} from "./actions"; } from "./actions";
const initialState = { const initialState = {
@ -21,7 +22,8 @@ const initialState = {
userPoints: null, userPoints: null,
selectedFeature: null, selectedFeature: null,
routingBarVisible: false, routingBarVisible: false,
isSearchingRoute: false isSearchingRoute: false,
setSelectedProjectIds: []
} }
function mapReducer(state = initialState, action) { function mapReducer(state = initialState, action) {
@ -46,6 +48,8 @@ function mapReducer(state = initialState, action) {
return { ...state, routingBarVisible: action.payload } return { ...state, routingBarVisible: action.payload }
case SET_IS_SEARCHING_ROUTE: case SET_IS_SEARCHING_ROUTE:
return { ...state, isSearchingRoute: action.payload } return { ...state, isSearchingRoute: action.payload }
case SET_SELECTED_PROJECT_IDS:
return { ...state, selectedProjectIds: action.payload }
default: default:
return state; return state;
} }

6
src/components/MapLeftContent/index.js

@ -3,7 +3,7 @@ import L from 'leaflet';
import { Button, Col, Drawer, Input, Row, Spin, Tree } from 'antd'; import { Button, Col, Drawer, Input, Row, Spin, Tree } from 'antd';
import ApiProject from '../../services/api/modules/project'; import ApiProject from '../../services/api/modules/project';
import { store } from '../../appredux/store'; import { store } from '../../appredux/store';
import { getUserPoints, setMapLoading, setOpenRight, setProjectTree, setSelectedFeature, setUserPoints } from '../../appredux/modules/map/actions'; import { getUserPoints, setMapLoading, setOpenRight, setProjectTree, setSelectedFeature, setSelectedProjectIds, setUserPoints } from '../../appredux/modules/map/actions';
import ContentLoader from 'react-content-loader'; import ContentLoader from 'react-content-loader';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import ApiMapMonitoring from '../../services/api/modules/map_monitoring'; import ApiMapMonitoring from '../../services/api/modules/map_monitoring';
@ -26,13 +26,15 @@ const MapLeftContent = () => {
}; };
const onCheck = (checkedKeys, info) => { const onCheck = (checkedKeys, info) => {
console.log('onCheck', checkedKeys, info); console.log('onCheck', checkedKeys, info);
if (checkedKeys.length < 1) { if (checkedKeys.length < 1) {
console.log('clear all user points');
store.dispatch(setUserPoints(null)); store.dispatch(setUserPoints(null));
store.dispatch(setOpenRight(false)); store.dispatch(setOpenRight(false));
store.dispatch(setSelectedFeature(null)); store.dispatch(setSelectedFeature(null));
store.dispatch(setSelectedProjectIds([]))
return; return;
} }
store.dispatch(setSelectedProjectIds(checkedKeys))
getUserPoints(); getUserPoints();
}; };

138
src/components/MapRightContent/index.js

@ -1,89 +1,129 @@
import React, { useEffect, useMemo, useRef, useState } from 'react' import React, { useEffect, useMemo, useRef, useState } from 'react'
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import PopupButtonActions from '../PopupButtonActions'; import PopupButtonActions from '../PopupButtonActions';
import DEFAULT_USER_ICON from '../../assets/img/avatars/user.png';
import './styles.css' import './styles.css'
import { BASE_SIMPRO_LUMEN_IMAGE } from '../../const/ApiConst';
import { Button, Image } from 'antd';
import {Icon} from '@iconify/react';
import closeCircle from '@iconify/icons-mdi/close-circle';
import closeIcon from '@iconify/icons-mdi/close';
import { closePopup } from '../../utils/MapUtils';
const MapRightContent = () => { const MapRightContent = () => {
const { mapLoading, selectedFeature } = useSelector(state => state.mapReducer); const { mapLoading, selectedFeature } = useSelector(state => state.mapReducer);
const PopupContent = useMemo(() => { // const PopupContent = useMemo(() => {
console.log('selectedFeature', selectedFeature); // console.log('selectedFeature', selectedFeature);
if (selectedFeature && selectedFeature.properties) { // if (selectedFeature && selectedFeature.properties) {
// let content = []; // // let content = [];
// for (let key in selectedFeature.properties) { // // for (let key in selectedFeature.properties) {
// content.push(<tr key={key}> // // content.push(<tr key={key}>
// <td>{`${key}`}</td> // // <td>{`${key}`}</td>
// <td>:</td> // // <td>:</td>
// <td>{`${selectedFeature.properties[key]}`}</td> // // <td>{`${selectedFeature.properties[key]}`}</td>
// </tr>) // // </tr>)
// } // // }
// console.log('content', content); // // console.log('content', content);
// return (
// <table className="table popup-table">
// <tbody>
// <tr>
// <td>Name</td>
// <td>:</td>
// <td>{selectedFeature?.properties['Name']}</td>
// </tr>
// <tr>
// <td>Clock in time</td>
// <td>:</td>
// <td>{selectedFeature?.properties['Clock in time']}</td>
// </tr>
// <tr>
// <td>Clock in location</td>
// <td>:</td>
// <td>{selectedFeature?.properties['Clock in location']}</td>
// </tr>
// <tr>
// <td>Clock out time</td>
// <td>:</td>
// <td>{selectedFeature?.properties['Clock out time']}</td>
// </tr>
// <tr>
// <td>Clock out location</td>
// <td>:</td>
// <td>{selectedFeature?.properties['Clock out location']}</td>
// </tr>
// </tbody>
// </table>
// )
// }
// }, [selectedFeature])
const renderListProject = (projects) => {
if (projects && projects.length > 0) {
return ( return (
<table className="table popup-table"> <div>
<tbody> <ul>
<tr> { projects.map(n => <li>{n.project_name}</li>) }
<td>Name</td> </ul>
<td>:</td> </div>
<td>{selectedFeature?.properties['Name']}</td>
</tr>
<tr>
<td>Clock in time</td>
<td>:</td>
<td>{selectedFeature?.properties['Clock in time']}</td>
</tr>
<tr>
<td>Clock in location</td>
<td>:</td>
<td>{selectedFeature?.properties['Clock in location']}</td>
</tr>
<tr>
<td>Clock out time</td>
<td>:</td>
<td>{selectedFeature?.properties['Clock out time']}</td>
</tr>
<tr>
<td>Clock out location</td>
<td>:</td>
<td>{selectedFeature?.properties['Clock out location']}</td>
</tr>
</tbody>
</table>
) )
} }
}, [selectedFeature]) }
const Content = useMemo(() => { const Content = useMemo(() => {
return ( return (
<div style={{ paddingLeft: 10 }}> <div key={'content_right'} style={{ paddingLeft: 10 }}>
<div style={{ backgroundColor: '#f0f0f0', padding: 10, marginBottom: 5, fontWeight: 'bold', fontSize: 16 }}> <div style={{ backgroundColor: '#f0f0f0', padding: 10, marginBottom: 5, fontWeight: 'bold', fontSize: 16 }}>
Detail Information <Button shape="circle" color='' icon={<Icon icon={closeIcon} width={25} height={25} />} size="middle" style={{marginRight: 20, justifyContent: 'center', display: 'inline-block'}}
onClick={closePopup}
/>
<div style={{display: "inline-block", verticalAlign: 'middle'}}>Detail Information</div>
</div> </div>
<div style={{height: '75vh', overflow: 'auto'}}> <div style={{height: '75vh', overflow: 'auto'}}>
<table className="table popup-table"> <table className="table popup-table">
<tbody> <tbody>
<tr> <tr key={'image'}>
<td colSpan={3} style={{justifyContent: 'center'}}>{selectedFeature?.properties['image'] ?
<Image
width={`100%`}
src={`${BASE_SIMPRO_LUMEN_IMAGE}/${selectedFeature?.properties['image']}`}
/>
:
<Image
width={`100%`}
src={DEFAULT_USER_ICON}
/>
}</td>
</tr>
<tr key={'name'}>
<td className='td-popup-label'>Name</td> <td className='td-popup-label'>Name</td>
<td>:</td> <td>:</td>
<td>{selectedFeature?.properties['Name']}</td> <td>{selectedFeature?.properties['Name']}</td>
</tr> </tr>
<tr> <tr key={'projects'}>
<td className='td-popup-label'>Projects</td>
<td>:</td>
<td>{renderListProject(selectedFeature?.properties['Projects'])}</td>
</tr>
<tr key={'clock_in_time'}>
<td className='td-popup-label'>Clock in time</td> <td className='td-popup-label'>Clock in time</td>
<td>:</td> <td>:</td>
<td>{selectedFeature?.properties['Clock in time']}</td> <td>{selectedFeature?.properties['Clock in time']}</td>
</tr> </tr>
<tr> <tr key={'clock_in_loc'}>
<td className='td-popup-label'>Clock in location</td> <td className='td-popup-label'>Clock in location</td>
<td>:</td> <td>:</td>
<td>{selectedFeature?.properties['Clock in location']}</td> <td>{selectedFeature?.properties['Clock in location']}</td>
</tr> </tr>
<tr> <tr key={'clock_out_time'}>
<td className='td-popup-label'>Clock out time</td> <td className='td-popup-label'>Clock out time</td>
<td>:</td> <td>:</td>
<td>{selectedFeature?.properties['Clock out time']}</td> <td>{selectedFeature?.properties['Clock out time']}</td>
</tr> </tr>
<tr> <tr key={'clock_out_loc'}>
<td className='td-popup-label'>Clock out location</td> <td className='td-popup-label'>Clock out location</td>
<td>:</td> <td>:</td>
<td>{selectedFeature?.properties['Clock out location']}</td> <td>{selectedFeature?.properties['Clock out location']}</td>

14
src/services/api/base.js

@ -35,24 +35,34 @@ export default class RequestApi {
axios.interceptors.response.use( axios.interceptors.response.use(
response => response, response => response,
async (error) => { async (error) => {
// console.log('error axios', error); // console.log('error axios', JSON.stringify(error));
if (error) { if (error) {
// console.log('stringify', JSON.stringify(error)); // console.log('stringify', JSON.stringify(error));
const err = JSON.parse(JSON.stringify(error)); const err = JSON.parse(JSON.stringify(error));
console.log('error', err);
if (err.name === 'AxiosError' && err.code === 'ERR_NETWORK') { if (err.name === 'AxiosError' && err.code === 'ERR_NETWORK') {
alert(err.message); alert(err.message);
return; return;
} }
if (err.response) { if (err.response) {
if (err.response.status === 307 || err.response.status === 403) { if (err.response.status === 307 || err.response.status === 403 || err.response.status === 401) {
// console.log(err.response); // console.log(err.response);
alert('Token expired, please re-login'); alert('Token expired, please re-login');
// clearAllState(); // clearAllState();
window.localStorage.clear(); window.localStorage.clear();
window.location.reload();
// this.props.history.replace('/login'); // this.props.history.replace('/login');
return; return;
} }
} }
if (err && err.message && err.message.includes('401')) {
alert('Token expired, please re-login');
// clearAllState();
window.localStorage.clear();
window.location.reload();
// this.props.history.replace('/login');
return;
}
return Promise.reject(error); return Promise.reject(error);
} }
} }

71
src/services/api/modules/map_monitoring/index.js

@ -1,46 +1,55 @@
import moment from "moment"; import moment from "moment";
import { store } from "../../../../appredux/store";
import { BASE_SIMPRO_LUMEN } from "../../../../const/ApiConst"; import { BASE_SIMPRO_LUMEN } from "../../../../const/ApiConst";
import RequestApi from '../../base'; import RequestApi from '../../base';
export default class ApiMapMonitoring extends RequestApi { export default class ApiMapMonitoring extends RequestApi {
static async search() { static async search() {
const URL = `${BASE_SIMPRO_LUMEN}/presence/search` const { selectedProjectIds } = store.getState().mapReducer;
const dateFrom = moment().subtract(7,'d').format('YYYY-MM-DD 00:00:00'); // const URL = `${BASE_SIMPRO_LUMEN}/presence/search`
const dateTo = moment().format('YYYY-MM-DD 23:59:00'); const URL = `${BASE_SIMPRO_LUMEN}/map-monitoring/search`
// const dateFrom = moment().subtract(7,'d').format('YYYY-MM-DD 00:00:00');
// const dateTo = moment().format('YYYY-MM-DD 23:59:00');
// const payload = {
// "columns": [
// {
// "logic_operator": "range",
// "name": "created_at",
// "operator": "AND",
// "value": dateFrom,
// "value1": dateTo
// }
// ],
// "joins": [
// {
// "column_join": "user_id",
// "column_results": [
// "username", "name"
// ],
// "name": "m_users"
// }
// ],
// "orders": {
// "ascending": false,
// "columns": [
// "created_at"
// ]
// },
// "paging": {
// "length": 25,
// "start": 0
// }
// }
const payload = { const payload = {
"columns": [ "project_id": selectedProjectIds
{
"logic_operator": "range",
"name": "created_at",
"operator": "AND",
"value": dateFrom,
"value1": dateTo
}
],
"joins": [
{
"column_join": "user_id",
"column_results": [
"username", "name"
],
"name": "m_users"
}
],
"orders": {
"ascending": false,
"columns": [
"created_at"
]
},
"paging": {
"length": 25,
"start": 0
}
} }
console.log('payload', payload);
return await RequestApi.Request().post( return await RequestApi.Request().post(
URL, URL,
payload, payload,
RequestApi.HeaderWithToken()).then(res => { RequestApi.HeaderWithToken()).then(res => {
// console.log('res map-monitoring', JSON.stringify(res));
if (res) { if (res) {
if (res && res.data && res.data.data) { if (res && res.data && res.data.data) {
// console.log('ApiPresence search', res.data.data) // console.log('ApiPresence search', res.data.data)

14
src/utils/MapUtils.js

@ -1,3 +1,4 @@
import { setOpenRight, setSelectedFeature } from "../appredux/modules/map/actions";
import { store } from "../appredux/store"; import { store } from "../appredux/store";
export const removeLayerByName = (layerName) => { export const removeLayerByName = (layerName) => {
@ -25,3 +26,16 @@ export const removeLayerByName = (layerName) => {
} }
} }
} }
export const closePopup = () => {
const { mymap, routingBarVisible } = store.getState().mapReducer;
if (!routingBarVisible) {
// only can close popup when routing mode is not visible
removeLayerByName('popupTemp');
store.dispatch(setOpenRight(false));
store.dispatch(setSelectedFeature(null));
// if (mymap) {
// mymap.invalidateSize();
// }
}
}

10
src/views/MapMonitoring/MapMonitoring.css

@ -8,7 +8,7 @@
margin-left: 45%; margin-left: 45%;
} }
.image-marker img { .image-marker-green img {
height: 40px !important; height: 40px !important;
width: 40px !important; width: 40px !important;
border-radius: 50%; border-radius: 50%;
@ -16,6 +16,14 @@
border-color: green; border-color: green;
} }
.image-marker-red img {
height: 40px !important;
width: 40px !important;
border-radius: 50%;
border: solid;
border-color: red;
}
.image-marker-active img { .image-marker-active img {
height: 40px !important; height: 40px !important;
width: 40px !important; width: 40px !important;

79
src/views/MapMonitoring/index.js

@ -3,12 +3,12 @@ import L from 'leaflet';
import { Button, Col, Drawer, Row, Spin, Tree } from 'antd'; import { Button, Col, Drawer, Row, Spin, Tree } from 'antd';
import ApiProject from '../../services/api/modules/project'; import ApiProject from '../../services/api/modules/project';
import { store } from '../../appredux/store'; import { store } from '../../appredux/store';
import { getUserPoints, setMapLoading, setMymap, setOpenLeft, setOpenRight, setProjectTree, setSelectedFeature, setUserPoints } from '../../appredux/modules/map/actions'; import { getUserPoints, setMapLoading, setMymap, setOpenLeft, setOpenRight, setProjectTree, setSelectedFeature, setSelectedProjectIds, setUserPoints } from '../../appredux/modules/map/actions';
import ContentLoader from 'react-content-loader'; import ContentLoader from 'react-content-loader';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import MapLeftContent from '../../components/MapLeftContent'; import MapLeftContent from '../../components/MapLeftContent';
import MapRightContent from '../../components/MapRightContent'; import MapRightContent from '../../components/MapRightContent';
import { removeLayerByName } from '../../utils/MapUtils'; import { closePopup, removeLayerByName } from '../../utils/MapUtils';
import RoutingBar from '../../components/RoutingBarV2'; import RoutingBar from '../../components/RoutingBarV2';
import Loader from "react-loader-spinner"; import Loader from "react-loader-spinner";
import "react-loader-spinner/dist/loader/css/react-spinner-loader.css"; import "react-loader-spinner/dist/loader/css/react-spinner-loader.css";
@ -17,7 +17,11 @@ 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 } from '../../const/ApiConst';
import DEFAULT_USER_ICON from '../../assets/img/avatars/user.png'; import DEFAULT_USER_ICON from '../../assets/img/avatars/user.png';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
import 'leaflet.markercluster/dist/MarkerCluster.css'
import 'leaflet.markercluster/dist/leaflet.markercluster.js'
import 'leaflet-control-geocoder/dist/Control.Geocoder.css'
import 'leaflet-control-geocoder/dist/Control.Geocoder.js'
const MapMonitoring = () => { const MapMonitoring = () => {
@ -33,11 +37,18 @@ const MapMonitoring = () => {
lng: 120.13025155062624 lng: 120.13025155062624
} }
const {userPoints, mymap, openLeft, openRight, routingBarVisible, userHistory, isSearchingRoute} = 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);
let markerCluster = L.markerClusterGroup({
name: "userPointLayer",
// disableClusteringAtZoom: 17,
showCoverageOnHover: false,
// spiderfyOnMaxZoom: false
});
useEffect(() => { useEffect(() => {
initMap(); initMap();
getMapLeftContent(); getMapLeftContent();
@ -58,7 +69,8 @@ const MapMonitoring = () => {
onEachFeature: onEachFeatureUserPoints, onEachFeature: onEachFeatureUserPoints,
pointToLayer: pointToLayerUserPoints pointToLayer: pointToLayerUserPoints
}); });
userPointLayer.addTo(mymap); // userPointLayer.addTo(mymap);
mymap.addLayer(markerCluster);
mymap.fitBounds(userPointLayer.getBounds()); mymap.fitBounds(userPointLayer.getBounds());
} }
} }
@ -87,14 +99,10 @@ const MapMonitoring = () => {
store.dispatch(setMymap(mymap)); store.dispatch(setMymap(mymap));
// setMymap(mymap); // setMymap(mymap);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }).addTo(mymap); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }).addTo(mymap);
// add searching location (nominatim) on map
L.Control.geocoder().addTo(mymap);
mymap.on('click', (e) => { mymap.on('click', (e) => {
if (!store.getState().mapReducer.routingBarVisible) { closePopup();
// only can close popup when routing mode is not visible
removeLayerByName('popupTemp');
store.dispatch(setOpenRight(false));
store.dispatch(setSelectedFeature(null));
}
}) })
} }
@ -102,7 +110,7 @@ const MapMonitoring = () => {
const getMapLeftContent = async () => { const getMapLeftContent = async () => {
store.dispatch(setMapLoading(true)); store.dispatch(setMapLoading(true));
let project = await ApiProject.list(); let project = await ApiProject.list();
console.log('project', project); // console.log('project', project);
if (project && project.status && project.data && project.data.length > 0) { if (project && project.status && project.data && project.data.length > 0) {
let projectData = [ let projectData = [
{ {
@ -118,6 +126,9 @@ const MapMonitoring = () => {
}) })
store.dispatch(setProjectTree(projectData)); store.dispatch(setProjectTree(projectData));
// console.log('projectData', projectData); // console.log('projectData', projectData);
let selectedProject = project.data.map(n => n.id);
// console.log('selectedProject', selectedProject);
store.dispatch(setSelectedProjectIds(selectedProject))
getUserPoints(); getUserPoints();
store.dispatch(setMapLoading(false)); store.dispatch(setMapLoading(false));
} }
@ -134,18 +145,22 @@ const MapMonitoring = () => {
}); });
} }
const pointToLayerUserPoints = (feature, latlng) => { const renderClassMarker = (feature) => {
// console.log('feature', feature); let output = 'image-marker-red';
// create a marker style if (selectedFeature?.properties?.user_id === feature?.properties?.user_id) {
// let logoMarkerStyle = L.Icon.extend({ output = 'image-marker-active';
// options: { }
// iconSize: [85, 90], else {
// iconAnchor: [38, 86], if (feature?.properties.presence_status === true) {
// popupAnchor: [0, -80] output = 'image-marker-green'
// } }
// }); }
// let logoMarker = new logoMarkerStyle({iconUrl: `${BASE_SIMPRO_LUMEN_IMAGE}/${feature.properties.image}`}); return output;
}
// styling points geojson
const pointToLayerUserPoints = (feature, latlng) => {
let imgSrc = DEFAULT_USER_ICON; let imgSrc = DEFAULT_USER_ICON;
if (feature && feature.properties && feature.properties.image && feature.properties.image !== '') { if (feature && feature.properties && feature.properties.image && feature.properties.image !== '') {
imgSrc = `${BASE_SIMPRO_LUMEN_IMAGE}/${feature.properties.image}` imgSrc = `${BASE_SIMPRO_LUMEN_IMAGE}/${feature.properties.image}`
@ -153,26 +168,20 @@ const MapMonitoring = () => {
let img = `<img src="${imgSrc}" />` let img = `<img src="${imgSrc}" />`
let logoMarker = L.divIcon({ let logoMarker = L.divIcon({
html: img, html: img,
className: 'image-marker', // className: feature?.properties?.presence_status ? 'image-marker-green' : 'image-marker-red',
className: renderClassMarker(feature),
iconSize: [40, 40], iconSize: [40, 40],
iconAnchor: [20, 50], iconAnchor: [20, 50],
popupAnchor: [0, -80] popupAnchor: [0, -80]
}); });
// let logoMarkerActive = L.divIcon({
// html: img,
// className: 'image-marker-active',
// iconSize: [40, 40],
// iconAnchor: [20, 50],
// popupAnchor: [0, -80]
// });
// read the coordinates from your marker // read the coordinates from your marker
let lat = feature.geometry.coordinates[1]; let lat = feature.geometry.coordinates[1];
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);
return marker; return marker;
} }
@ -238,7 +247,7 @@ const MapMonitoring = () => {
return ( return (
<Row> <Row>
<Col span={gridLeft}> <Col span={gridLeft}>
<MapLeftContent /> <MapLeftContent key={'map_left_content'} />
</Col> </Col>
<Col span={gridMiddle}> <Col span={gridMiddle}>
<div id="map-area" style={{ height: '90vh', width: '100%' }} ref={mapRef}></div> <div id="map-area" style={{ height: '90vh', width: '100%' }} ref={mapRef}></div>
@ -261,7 +270,7 @@ const MapMonitoring = () => {
)} )}
</Col> </Col>
<Col span={gridRight}> <Col span={gridRight}>
<MapRightContent /> <MapRightContent key={'map_right_content'} />
</Col> </Col>
<ToastContainer autoClose={5000} /> <ToastContainer autoClose={5000} />
</Row> </Row>

Loading…
Cancel
Save