Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion frontend/.env.expand
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ REACT_APP_IMAGE_UPLOAD_API_URL=$TM_IMAGE_UPLOAD_API_URL
REACT_APP_HOMEPAGE_VIDEO_URL=$TM_HOMEPAGE_VIDEO_URL
REACT_APP_HOMEPAGE_IMG_HIGH=$TM_HOMEPAGE_IMG_HIGH
REACT_APP_HOMEPAGE_IMG_LOW=$TM_HOMEPAGE_IMG_LOW
REACT_APP_MAPBOX_TOKEN=$TM_MAPBOX_TOKEN
REACT_APP_ENABLE_SERVICEWORKER=$TM_ENABLE_SERVICEWORKER
REACT_APP_MAX_FILESIZE=$TM_IMPORT_MAX_FILESIZE
REACT_APP_MAX_AOI_AREA=$TM_MAX_AOI_AREA
Expand Down
5 changes: 2 additions & 3 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
"dependencies": {
"@hotosm/id": "^2.34.0",
"@hotosm/iso-countries-languages": "^1.1.2",
"@mapbox/mapbox-gl-draw": "^1.4.3",
"@mapbox/mapbox-gl-language": "^0.10.1",
"@maplibre/maplibre-gl-geocoder": "^1.9.0",
"@placemarkio/geo-viewport": "^1.0.2",
"@rapideditor/rapid": "^2.5.2",
Expand All @@ -26,6 +24,7 @@
"@turf/transform-scale": "^6.5.0",
"@turf/truncate": "^6.5.0",
"@uiw/react-md-editor": "^3.22.0",
"@watergis/maplibre-gl-terradraw": "^1.9.5",
"axios": "^1.6.7",
"chart.js": "^4.4.1",
"chartjs-adapter-date-fns": "^3.0.0",
Expand All @@ -36,7 +35,6 @@
"fromentries": "^1.3.2",
"h3-js": "^4.1.0",
"humanize-duration": "^3.31.0",
"mapbox-gl-draw-rectangle-mode": "^1.0.4",
"maplibre-gl": "^5.6.0",
"marked": "^4.3.0",
"osmtogeojson": "^3.0.0-beta.5",
Expand Down Expand Up @@ -69,6 +67,7 @@
"slug": "^8.2.3",
"swiper": "^11.1.4",
"tachyons": "^4.12.0",
"terra-draw": "^1.18.1",
"tributejs": "^5.1.3",
"use-query-params": "^2.2.1",
"webfontloader": "^1.6.28",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import { FormattedMessage } from 'react-intl';
import PropTypes from 'prop-types';
import 'maplibre-gl/dist/maplibre-gl.css';

import { MAPBOX_TOKEN, MAP_STYLE, CHART_COLOURS } from '../../config';
import { MAP_STYLE, CHART_COLOURS } from '../../config';
import messages from './messages';
import './contributionsHeatmap.css';

maplibregl.accessToken = MAPBOX_TOKEN;

export const ContributionsHeatmap = ({ contributionsByGeo = [] }) => {
const mapContainer = useRef(null);
const map = useRef(null);
Expand Down Expand Up @@ -171,7 +169,7 @@ export const ContributionsHeatmap = ({ contributionsByGeo = [] }) => {
const currentZoom = map.current.getZoom();
const h3ResBasedOnZoom =
currentZoom >= 1
? zoomToH3ResMapping[parseInt(currentZoom)] ?? Math.floor((currentZoom - 2) * 0.7)
? zoomToH3ResMapping[Number.parseInt(currentZoom)] ?? Math.floor((currentZoom - 2) * 0.7)
: 1;

map.current.getSource('hexbin').setData({
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/partners/currentProjects.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function CurrentProjects({ currentProjects }) {

const fetchData = async () => {
try {
const projectIds = currentProjects.split(',').map((id) => parseInt(id.trim(), 10));
const projectIds = currentProjects.split(',').map((id) => Number.parseInt(id.trim(), 10));
const promises = projectIds.map(async (id) => {
const response = await fetch(API_URL + `projects/${id}/tasks/`);

Expand Down
83 changes: 60 additions & 23 deletions frontend/src/components/projectCreate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import bbox from '@turf/bbox';
import { featureCollection } from '@turf/helpers';
import truncate from '@turf/truncate';
import toast from 'react-hot-toast';
import MapboxDraw from '@mapbox/mapbox-gl-draw';
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
import { MaplibreTerradrawControl } from '@watergis/maplibre-gl-terradraw';
import '@watergis/maplibre-gl-terradraw/dist/maplibre-gl-terradraw.css';
import { TerraDrawPolygonMode } from 'terra-draw';

import messages from './messages';
import viewsMessages from '../../views/messages';
Expand All @@ -33,11 +34,36 @@ import {
verifyFileSize,
} from '../../utils/geoFileFunctions';
import { getErrorMsg } from './fileUploadErrors';
import { getAllFeatures, removeFeaturesById } from '../../utils/terrawDraw';

const ProjectCreationMap = lazy(() =>
import('./projectCreationMap' /* webpackChunkName: "projectCreationMap" */),
);

const polygonModeStyles = {
fillColor: '#F1EE8E',
fillOpacity: 0.3,
outlineColor: '#E69B00',
outlineWidth: 1,
closingPointColor: '#F1EE8E',
closingPointWidth: 1,
closingPointOutlineColor: '#E69B00',
closingPointOutlineWidth: 1,
};

//this function Overrides default Terra Draw polygon layer styles to match our theme
const setPolygonStyle = (map) => {
const defaultTdPolygonLayerId = 'td-polygon';
const defaultTdPolygonOutlineLayerId = 'td-polygon-outline';
const defaultTdPolygonPointLayerId = 'td-point';

map.setPaintProperty(defaultTdPolygonLayerId, 'fill-color', '#F1EE8E');
map.setPaintProperty(defaultTdPolygonLayerId, 'fill-opacity', 0.3);
map.setPaintProperty(defaultTdPolygonOutlineLayerId, 'line-color', '#E69B00');
map.setPaintProperty(defaultTdPolygonOutlineLayerId, 'line-width', 1);
map.setPaintProperty(defaultTdPolygonPointLayerId, 'circle-color', '#E69B00');
};

const ProjectCreate = () => {
const intl = useIntl();
const token = useSelector((state) => state.auth.token);
Expand Down Expand Up @@ -94,40 +120,46 @@ const ProjectCreate = () => {
};

const deleteHandler = () => {
const features = mapObj.draw.getAll();
if (features.features.length > 0) {
const id = features.features[0].id;
mapObj.draw.delete(id);
}

const drawInstance = mapObj.draw.getTerraDrawInstance();
drawInstance.clear();
if (mapObj.map.getSource('aoi')) {
mapObj.map.getSource('aoi').setData(featureCollection([]));
}
updateMetadata({ ...metadata, area: 0, geom: null, arbitraryTasks: false, tasksNumber: 0 });
};

const drawHandler = () => {
const drawInstance = mapObj.draw.getTerraDrawInstance();
if (!drawInstance) return;
if (drawModeIsActive) {
setDrawModeIsActive(false);
mapObj.draw.changeMode('simple_select');
drawInstance.setMode('select');
return;
}
setDrawModeIsActive(true);
const updateArea = (event) => {
const features = mapObj.draw.getAll();
if (features.features.length > 1) {
const id = features.features[0].id;
mapObj.draw.delete(id);
}

// Validate area first.
setDataGeom(featureCollection(event.features), false);
drawInstance.setMode('polygon');
drawInstance.on('finish', (id) => {
const allFeatures = getAllFeatures(drawInstance);
// keep the latest one and remove everything else
const previousFeatureIds = allFeatures.reduce(
(prev, curr) => (curr.id !== id ? [...prev, curr.id] : prev),
[],
);
const newFeature = allFeatures.filter((f) => f.id === id);

if (previousFeatureIds.length > 0) {
removeFeaturesById(drawInstance, previousFeatureIds);
}
setDataGeom(featureCollection(newFeature), false);
drawInstance.setMode('select');
drawInstance.selectFeature(id);
setDrawModeIsActive(false);
};

mapObj.map.on('draw.update', updateArea);
mapObj.map.once('draw.create', updateArea);
mapObj.draw.changeMode('draw_polygon');
// Note: We are manually overriding Terra Draw's default layer paint properties
// because the β€œselect” mode style config may not apply as expected.
setPolygonStyle(mapObj.map);
});
};
// eslint-disable-next-line
const [cloneFromId, setCloneFromId] = useQueryParam('cloneFrom', NumberParam);
Expand Down Expand Up @@ -182,11 +214,16 @@ const ProjectCreate = () => {
}, [metadata.area]);

const drawOptions = {
displayControlsDefault: false,
modes: ['delete', 'polygon', 'select'],
open: true,
modeOptions: {
polygon: new TerraDrawPolygonMode({ styles: polygonModeStyles }),
},
};

const [mapObj, setMapObj] = useState({
map: null,
draw: new MapboxDraw(drawOptions),
draw: new MaplibreTerradrawControl(drawOptions),
});

const handleCreate = useCallback(
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/components/projectCreate/navButtons.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { FormattedMessage, useIntl } from 'react-intl';
import messages from './messages';
import { Button } from '../button';
import { useAsync } from '../../hooks/UseAsync';
import { removeFeaturesById } from '../../utils/terrawDraw';

const clearParamsStep = (props) => {
switch (props.index) {
Expand Down Expand Up @@ -58,7 +59,8 @@ const NavButtons = (props) => {
return { error: true, message: message };
} else {
const id = props.metadata.geom.features[0].id;
props.mapObj.draw.delete(id);
const drawInstance = props.mapObj.draw.getTerraDrawInstance();
removeFeaturesById(drawInstance, [id]);
props.mapObj.map.getSource('aoi').setData(props.metadata.geom);
props.updateMetadata({
...props.metadata,
Expand Down
49 changes: 3 additions & 46 deletions frontend/src/components/projectCreate/projectCreationMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,19 @@ import { useSelector } from 'react-redux';
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import { featureCollection } from '@turf/helpers';
import MapboxLanguage from '@mapbox/mapbox-gl-language';
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder';
import '@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css';
import { useDropzone } from 'react-dropzone';

import { maplibreLayerDefn } from '../projects/projectsMap';
import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage';

import {
MAPBOX_TOKEN,
CHART_COLOURS,
TASK_COLOURS,
baseLayers,
DEFAULT_MAP_STYLE,
} from '../../config';
import { CHART_COLOURS, TASK_COLOURS, baseLayers, DEFAULT_MAP_STYLE } from '../../config';
import { fetchLocalJSONAPI } from '../../network/genericJSONRequest';
import { useDebouncedCallback } from '../../hooks/UseThrottle';
import isWebglSupported from '../../utils/isWebglSupported';
import useSetRTLTextPlugin from '../../utils/useSetRTLTextPlugin';
import { BasemapMenu } from '../basemapMenu';
import { ProjectsAOILayerCheckBox } from './projectsAOILayerCheckBox';
import WebglUnsupported from '../webglUnsupported';

maplibregl.accessToken = MAPBOX_TOKEN;
import '../projectEdit/style.scss';

const ProjectCreationMap = ({
mapObj,
Expand All @@ -37,7 +26,6 @@ const ProjectCreationMap = ({
uploadFile,
}: Object) => {
const mapRef = createRef();
const mapboxSupportedLanguage = useMapboxSupportedLanguage();
const token = useSelector((state) => state.auth.token);
const [showProjectsAOILayer, setShowProjectsAOILayer] = useState(true);
const [aoiCanBeActivated, setAOICanBeActivated] = useState(false);
Expand Down Expand Up @@ -93,20 +81,7 @@ const ProjectCreationMap = ({
attributionControl: false,
})
.addControl(new maplibregl.AttributionControl({ compact: false }))
.addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage }))
.addControl(new maplibregl.ScaleControl({ unit: 'metric' }));
if (MAPBOX_TOKEN) {
map.addControl(
new MaplibreGeocoder({
accessToken: MAPBOX_TOKEN,
maplibregl,
marker: false,
collapsed: true,
language: mapboxSupportedLanguage,
}),
'top-right',
);
}

setMapObj({ ...mapObj, map: map });
return () => {
Expand Down Expand Up @@ -264,7 +239,7 @@ const ProjectCreationMap = ({
});

// Remove area and geometry when aoi is deleted.
mapObj.map.on('draw.delete', (event) => {
mapObj.map.on('delete', (event) => {
updateMetadata({ ...metadata, geom: null, area: 0 });
});
// enable disable the project AOI visualization checkbox
Expand All @@ -275,24 +250,6 @@ const ProjectCreationMap = ({
setAOICanBeActivated(true);
}
});

mapObj.map.on('style.load', (event) => {
if (!MAPBOX_TOKEN) {
return;
}
addMapLayers(mapObj.map);
const features = mapObj.draw.getAll();
if (features.features.length === 0 && mapObj.map.getSource('aoi') !== undefined) {
mapObj.map.getSource('aoi').setData(metadata.geom);
}

if (metadata.taskGrid && step !== 1 && mapObj.map.getSource('grid') !== undefined) {
mapObj.map.getSource('grid').setData(metadata.taskGrid);
} else {
mapObj.map.getSource('grid') &&
mapObj.map.getSource('grid').setData(featureCollection([]));
}
});
}
// eslint-disable-next-line
}, [mapObj, metadata, updateMetadata, step]);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/projectDetail/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ export const ProjectDetail = (props) => {
size={'large'}
textColor="white"
users={contributors}
maxLength={parseInt(size[0] / 75) > 12 ? 12 : parseInt(size[0] / 75)}
maxLength={Number.parseInt(size[0] / 75) > 12 ? 12 : Number.parseInt(size[0] / 75)}
/>
)}
</div>
Expand Down
Loading