From f600df0c5eea022cb4d56ece22282453068d50ab Mon Sep 17 00:00:00 2001 From: Sujit Date: Tue, 3 Sep 2024 15:16:43 +0545 Subject: [PATCH 01/20] feat: update the base layer list --- .../BaseLayerSwitcher/baseLayers.tsx | 152 +++++++++--------- 1 file changed, 73 insertions(+), 79 deletions(-) diff --git a/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/baseLayers.tsx b/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/baseLayers.tsx index ec58c541..d0f1fc01 100644 --- a/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/baseLayers.tsx +++ b/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/baseLayers.tsx @@ -1,102 +1,96 @@ const baseLayersData = { osm: { - version: 8, - sources: { - osm: { - type: 'raster', - tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'], - tileSize: 256, - attribution: - 'Map tiles by OpenStreetMap tile servers, under the tile usage policy. Data by OpenStreetMap', - }, + source: { + type: 'raster', + tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'], + tileSize: 256, + attribution: + 'Map tiles by OpenStreetMap tile servers, under the tile usage policy. Data by OpenStreetMap', }, - layers: [ - { - id: 'osm', - type: 'raster', - source: 'osm', + layer: { + id: 'osm', + type: 'raster', + source: 'osm', + layout: { + visibility: 'none', }, - ], + }, }, + 'osm-light': { - version: 8, - sources: { - 'osm-light': { - type: 'raster', - tiles: [ - 'https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', - 'https://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', - 'https://c.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', - ], - tileSize: 256, - attribution: '', - maxzoom: 18, - }, + source: { + type: 'raster', + tiles: [ + 'https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', + 'https://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', + 'https://c.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', + ], + tileSize: 256, + attribution: + 'Map tiles by OpenStreetMap tile servers, under the tile usage policy. Data by OpenStreetMap', + maxzoom: 18, }, - layers: [ - { - id: 'osm-light', - type: 'raster', - source: 'osm-light', + layer: { + id: 'osm-light', + type: 'raster', + source: 'osm-light', + layout: { + visibility: 'none', }, - ], + }, }, satellite: { - version: 8, - sources: { - satellite: { - type: 'raster', - tiles: [ - 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', - ], - tileSize: 256, - attribution: '', - maxzoom: 18, - }, + source: { + type: 'raster', + tiles: [ + 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', + ], + tileSize: 256, + attribution: 'ArcGIS', + maxzoom: 18, }, - layers: [ - { - id: 'satellite', - type: 'raster', - source: 'satellite', + layer: { + id: 'satellite', + type: 'raster', + source: 'satellite', + layout: { + visibility: 'none', }, - ], + }, }, topo: { - version: 8, - sources: { - topo: { - type: 'raster', - tiles: [ - 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', - ], - maxZoom: 18, - }, + source: { + type: 'raster', + tiles: [ + 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', + ], + maxZoom: 18, + attribution: 'ArcGIS', }, - layers: [ - { - id: 'topo', - type: 'raster', - source: 'topo', + layer: { + id: 'topo', + type: 'raster', + source: 'topo', + layout: { + visibility: 'none', }, - ], + }, }, hybrid: { - version: 8, - sources: { - hybrid: { - type: 'raster', - tiles: ['https://mt1.google.com/vt/lyrs=p&x={x}&y={y}&z={z}'], - maxZoom: 18, - }, + source: { + type: 'raster', + tiles: ['https://mt1.google.com/vt/lyrs=p&x={x}&y={y}&z={z}'], + maxZoom: 18, + attribution: 'ArcGIS', }, - layers: [ - { - id: 'hybrid', - type: 'raster', - source: 'hybrid', + layer: { + id: 'hybrid', + type: 'raster', + source: 'hybrid', + layout: { + visibility: 'none', }, - ], + }, }, }; From 6541814fe06861d402aff2dbd9bfd0a4362c2e39 Mon Sep 17 00:00:00 2001 From: Sujit Date: Tue, 3 Sep 2024 15:18:18 +0545 Subject: [PATCH 02/20] refactor: base layer switching logic --- .../BaseLayerSwitcher/index.tsx | 51 +++++++------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/index.tsx b/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/index.tsx index f975667f..48e2fb95 100644 --- a/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/index.tsx +++ b/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/index.tsx @@ -1,47 +1,34 @@ -import { useCallback, useEffect } from 'react'; +import { useEffect, useRef } from 'react'; import { IBaseLayerSwitcher } from '../types'; import baseLayersData from './baseLayers'; -let layersCache = {}; - export default function BaseLayerSwitcher({ map, baseLayers = baseLayersData, activeLayer = 'osm', }: IBaseLayerSwitcher) { - const changeStyle = useCallback(() => { - if (!map?.isStyleLoaded || !map.getStyle()) return; - const { sources, layers } = map.getStyle(); - if (activeLayer in sources || !(activeLayer in baseLayers)) return; - layersCache = sources; - layers.forEach(layer => { - // @ts-ignore - if (!layersCache[layer.id]) return; - // @ts-ignore - layersCache[layer.id].layer = layer; - }); - // @ts-ignore - map.setStyle(baseLayers[activeLayer]); - Object.keys(layersCache).forEach(key => { - // @ts-ignore - const { type, data, layer } = layersCache[key]; - if (!data || !layer) return; - map.addSource(key, { type, data }); - map.addLayer({ id: key, ...layer }); - map.off('style.load', changeStyle); - }); - }, [map, baseLayers, activeLayer]); + const previouslyActiveLayer = useRef(activeLayer); + // add all base layers to map useEffect(() => { - if (!map) return () => {}; - map.once('style.load', changeStyle); - return () => map.off('style.load', changeStyle); - }, [map, activeLayer, baseLayers, changeStyle]); + if (!map) return; + Object.entries(baseLayers).forEach(([key, { layer, source }]) => { + map.addSource(key, source); + map.addLayer(layer); + }); + if (!map.getLayer(activeLayer)) return; + map.setLayoutProperty(activeLayer, 'visibility', 'visible'); + previouslyActiveLayer.current = activeLayer; + }, [map, baseLayers]); // eslint-disable-line + // change visibility layout property based on active layer useEffect(() => { - if (!map || !map.isStyleLoaded) return; - changeStyle(); - }, [map, activeLayer, changeStyle]); + if (!map) return; + map.setLayoutProperty(previouslyActiveLayer.current, 'visibility', 'none'); + if (!map.getLayer(activeLayer)) return; + map.setLayoutProperty(activeLayer, 'visibility', 'visible'); + previouslyActiveLayer.current = activeLayer; + }, [map, activeLayer]); return null; } From 05252839aa0752aab52b87bc95466945e9ee37c6 Mon Sep 17 00:00:00 2001 From: Sujit Date: Tue, 3 Sep 2024 15:20:07 +0545 Subject: [PATCH 03/20] feat(individual-project): add `BaseLayerSwitcherUI` for baselayer switching --- .../common/BaseLayerSwitcher/index.tsx | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/frontend/src/components/common/BaseLayerSwitcher/index.tsx diff --git a/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx b/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx new file mode 100644 index 00000000..17ba7dd3 --- /dev/null +++ b/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx @@ -0,0 +1,69 @@ +import { useState } from 'react'; +import useOutsideClick from '@Hooks/useOutsideClick'; +import BaseLayerSwitcher from '../MapLibreComponents/BaseLayerSwitcher'; +import baseLayersData from '../MapLibreComponents/BaseLayerSwitcher/baseLayers'; +import { MapInstanceType } from '../MapLibreComponents/types'; + +interface IBaseLayerSwitcherUIProps { + map?: MapInstanceType; + baseLayerList?: object; +} + +const BaseLayerSwitcherUI = ({ + map, + baseLayerList = baseLayersData, +}: IBaseLayerSwitcherUIProps) => { + const [selectedBaseLayer, setSelectedBaseLayer] = useState('osm'); + // eslint-disable-next-line no-unused-vars + const [_, toggle, handleToggle]: any = useOutsideClick('single'); + + return ( + <> +
{ + handleToggle(); + }} + role="presentation" + > + + layers + +
+ {toggle && ( +
+ {Object.entries(baseLayerList)?.map(([key]) => ( +
+ { + setSelectedBaseLayer(e.target.value); + handleToggle(); + }} + /> + +
+ ))} +
+ )} + + + + ); +}; + +export default BaseLayerSwitcherUI; From 34172af726cb9ec28f7e01f50e88b99661ec3c91 Mon Sep 17 00:00:00 2001 From: Sujit Date: Tue, 3 Sep 2024 15:37:57 +0545 Subject: [PATCH 04/20] fix: check if map is loaded before adding baselayer --- .../src/components/common/BaseLayerSwitcher/index.tsx | 3 +++ .../MapLibreComponents/BaseLayerSwitcher/index.tsx | 9 +++++---- .../components/common/MapLibreComponents/types/index.ts | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx b/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx index 17ba7dd3..31639a69 100644 --- a/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx +++ b/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx @@ -7,11 +7,13 @@ import { MapInstanceType } from '../MapLibreComponents/types'; interface IBaseLayerSwitcherUIProps { map?: MapInstanceType; baseLayerList?: object; + isMapLoaded: Boolean; } const BaseLayerSwitcherUI = ({ map, baseLayerList = baseLayersData, + isMapLoaded, }: IBaseLayerSwitcherUIProps) => { const [selectedBaseLayer, setSelectedBaseLayer] = useState('osm'); // eslint-disable-next-line no-unused-vars @@ -61,6 +63,7 @@ const BaseLayerSwitcherUI = ({ activeLayer={selectedBaseLayer} baseLayers={baseLayerList} map={map} + isMapLoaded={isMapLoaded} /> ); diff --git a/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/index.tsx b/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/index.tsx index 48e2fb95..ffcfdb52 100644 --- a/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/index.tsx +++ b/src/frontend/src/components/common/MapLibreComponents/BaseLayerSwitcher/index.tsx @@ -6,12 +6,13 @@ export default function BaseLayerSwitcher({ map, baseLayers = baseLayersData, activeLayer = 'osm', + isMapLoaded, }: IBaseLayerSwitcher) { const previouslyActiveLayer = useRef(activeLayer); // add all base layers to map useEffect(() => { - if (!map) return; + if (!map || !isMapLoaded) return; Object.entries(baseLayers).forEach(([key, { layer, source }]) => { map.addSource(key, source); map.addLayer(layer); @@ -19,16 +20,16 @@ export default function BaseLayerSwitcher({ if (!map.getLayer(activeLayer)) return; map.setLayoutProperty(activeLayer, 'visibility', 'visible'); previouslyActiveLayer.current = activeLayer; - }, [map, baseLayers]); // eslint-disable-line + }, [map, baseLayers, isMapLoaded]); // eslint-disable-line // change visibility layout property based on active layer useEffect(() => { - if (!map) return; + if (!map || !isMapLoaded) return; map.setLayoutProperty(previouslyActiveLayer.current, 'visibility', 'none'); if (!map.getLayer(activeLayer)) return; map.setLayoutProperty(activeLayer, 'visibility', 'visible'); previouslyActiveLayer.current = activeLayer; - }, [map, activeLayer]); + }, [map, activeLayer, isMapLoaded]); return null; } diff --git a/src/frontend/src/components/common/MapLibreComponents/types/index.ts b/src/frontend/src/components/common/MapLibreComponents/types/index.ts index e770cbd2..5d87551d 100644 --- a/src/frontend/src/components/common/MapLibreComponents/types/index.ts +++ b/src/frontend/src/components/common/MapLibreComponents/types/index.ts @@ -28,6 +28,7 @@ export interface IBaseLayerSwitcher { map?: MapInstanceType; baseLayers?: object; activeLayer?: string; + isMapLoaded: Boolean; } export interface ILayer { From 120454864349fc24e9e48a38cb5a9ce63abe9c3f Mon Sep 17 00:00:00 2001 From: Sujit Date: Tue, 3 Sep 2024 15:42:40 +0545 Subject: [PATCH 05/20] feat: add `LocateTheUser` component to redirect user to their current location --- .../MapLibreComponents/LocateUser/index.tsx | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/frontend/src/components/common/MapLibreComponents/LocateUser/index.tsx diff --git a/src/frontend/src/components/common/MapLibreComponents/LocateUser/index.tsx b/src/frontend/src/components/common/MapLibreComponents/LocateUser/index.tsx new file mode 100644 index 00000000..15c1520a --- /dev/null +++ b/src/frontend/src/components/common/MapLibreComponents/LocateUser/index.tsx @@ -0,0 +1,27 @@ +import { GeolocateControl } from 'maplibre-gl'; +import { useEffect } from 'react'; +import { MapInstanceType } from '../types'; + +interface ILocateTheUserProps { + map?: MapInstanceType; + isMapLoaded: Boolean; +} + +const LocateUser = ({ map, isMapLoaded }: ILocateTheUserProps) => { + useEffect(() => { + if (!map || !isMapLoaded) return; + // Add geolocate control to the map. + map.addControl( + new GeolocateControl({ + positionOptions: { + enableHighAccuracy: true, + }, + trackUserLocation: true, + }), + ); + }, [map, isMapLoaded]); + + return null; +}; + +export default LocateUser; From dff20228e94e4ccbca6147409cd1802c2d60203e Mon Sep 17 00:00:00 2001 From: Sujit Date: Tue, 3 Sep 2024 15:44:55 +0545 Subject: [PATCH 06/20] feat(individual-project): add base layer switcher --- .../src/components/IndividualProject/MapSection/index.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/components/IndividualProject/MapSection/index.tsx b/src/frontend/src/components/IndividualProject/MapSection/index.tsx index e7c3dd2b..5d696aa1 100644 --- a/src/frontend/src/components/IndividualProject/MapSection/index.tsx +++ b/src/frontend/src/components/IndividualProject/MapSection/index.tsx @@ -6,12 +6,11 @@ import { useTypedSelector, useTypedDispatch } from '@Store/hooks'; import { useMapLibreGLMap } from '@Components/common/MapLibreComponents'; import VectorLayer from '@Components/common/MapLibreComponents/Layers/VectorLayer'; import MapContainer from '@Components/common/MapLibreComponents/MapContainer'; -import BaseLayerSwitcher from '@Components/common/MapLibreComponents/BaseLayerSwitcher'; import { GeojsonType } from '@Components/common/MapLibreComponents/types'; import AsyncPopup from '@Components/common/MapLibreComponents/AsyncPopup'; import getBbox from '@turf/bbox'; import { FeatureCollection } from 'geojson'; -import { LngLatBoundsLike, Map } from 'maplibre-gl'; +import { GeolocateControl, LngLatBoundsLike, Map } from 'maplibre-gl'; import { setProjectState } from '@Store/actions/project'; import { useGetProjectsDetailQuery, @@ -23,6 +22,8 @@ import { postTaskStatus } from '@Services/project'; import { useMutation } from '@tanstack/react-query'; import { toast } from 'react-toastify'; import hasErrorBoundary from '@Utils/hasErrorBoundary'; +import baseLayersData from '@Components/common/MapLibreComponents/BaseLayerSwitcher/baseLayers'; +import BaseLayerSwitcherUI from '@Components/common/BaseLayerSwitcher'; import Legend from './Legend'; const MapSection = () => { @@ -156,6 +157,8 @@ const MapSection = () => { height: '100%', }} > + + {projectArea && ( { } /> - ); }; From a2ed095661cfec6932f031f4547b46332d2553ba Mon Sep 17 00:00:00 2001 From: Sujit Date: Tue, 3 Sep 2024 16:30:50 +0545 Subject: [PATCH 07/20] feat(individual-project): add geolocate control to redirect user to current location --- .../src/components/IndividualProject/MapSection/index.tsx | 2 ++ .../components/common/MapLibreComponents/LocateUser/index.tsx | 1 + src/frontend/src/components/common/MapLibreComponents/map.css | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/src/frontend/src/components/IndividualProject/MapSection/index.tsx b/src/frontend/src/components/IndividualProject/MapSection/index.tsx index 5d696aa1..2d9035ca 100644 --- a/src/frontend/src/components/IndividualProject/MapSection/index.tsx +++ b/src/frontend/src/components/IndividualProject/MapSection/index.tsx @@ -24,6 +24,7 @@ import { toast } from 'react-toastify'; import hasErrorBoundary from '@Utils/hasErrorBoundary'; import baseLayersData from '@Components/common/MapLibreComponents/BaseLayerSwitcher/baseLayers'; import BaseLayerSwitcherUI from '@Components/common/BaseLayerSwitcher'; +import LocateUser from '@Components/common/MapLibreComponents/LocateUser'; import Legend from './Legend'; const MapSection = () => { @@ -158,6 +159,7 @@ const MapSection = () => { }} > + {projectArea && ( { }, trackUserLocation: true, }), + 'top-left', ); }, [map, isMapLoaded]); diff --git a/src/frontend/src/components/common/MapLibreComponents/map.css b/src/frontend/src/components/common/MapLibreComponents/map.css index cb66176e..866b9fa3 100644 --- a/src/frontend/src/components/common/MapLibreComponents/map.css +++ b/src/frontend/src/components/common/MapLibreComponents/map.css @@ -10,3 +10,7 @@ padding: 0; border-radius: 8px; } + +.maplibregl-ctrl-top-left { + margin-top: 40px; +} From ec30b69ea132b963bc27afbf2cb67be8e8a227b7 Mon Sep 17 00:00:00 2001 From: Sujit Date: Tue, 3 Sep 2024 16:50:41 +0545 Subject: [PATCH 08/20] refactor: make isMapLoaded optional prop on baselayer switcher --- .../src/components/common/BaseLayerSwitcher/index.tsx | 5 ++--- .../src/components/common/MapLibreComponents/types/index.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx b/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx index 31639a69..7ca166a2 100644 --- a/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx +++ b/src/frontend/src/components/common/BaseLayerSwitcher/index.tsx @@ -7,7 +7,7 @@ import { MapInstanceType } from '../MapLibreComponents/types'; interface IBaseLayerSwitcherUIProps { map?: MapInstanceType; baseLayerList?: object; - isMapLoaded: Boolean; + isMapLoaded?: Boolean; } const BaseLayerSwitcherUI = ({ @@ -22,8 +22,7 @@ const BaseLayerSwitcherUI = ({ return ( <>
{ handleToggle(); }} diff --git a/src/frontend/src/components/common/MapLibreComponents/types/index.ts b/src/frontend/src/components/common/MapLibreComponents/types/index.ts index 5d87551d..4155a0af 100644 --- a/src/frontend/src/components/common/MapLibreComponents/types/index.ts +++ b/src/frontend/src/components/common/MapLibreComponents/types/index.ts @@ -28,7 +28,7 @@ export interface IBaseLayerSwitcher { map?: MapInstanceType; baseLayers?: object; activeLayer?: string; - isMapLoaded: Boolean; + isMapLoaded?: Boolean; } export interface ILayer { From c45f14594b040176dc61d4075085ec227073d0ad Mon Sep 17 00:00:00 2001 From: Sujit Date: Tue, 3 Sep 2024 16:57:18 +0545 Subject: [PATCH 09/20] fix: move base layer switcher before waypoint layer --- .../CreateProject/FormContents/DefineAOI/MapSection/index.tsx | 4 ++-- .../src/components/DroneOperatorTask/MapSection/index.tsx | 4 ++-- src/frontend/src/components/Projects/MapSection/index.tsx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/components/CreateProject/FormContents/DefineAOI/MapSection/index.tsx b/src/frontend/src/components/CreateProject/FormContents/DefineAOI/MapSection/index.tsx index c95cb01d..85420c10 100644 --- a/src/frontend/src/components/CreateProject/FormContents/DefineAOI/MapSection/index.tsx +++ b/src/frontend/src/components/CreateProject/FormContents/DefineAOI/MapSection/index.tsx @@ -104,6 +104,8 @@ const MapSection = ({ position: 'relative', }} > + + {(drawNoFlyZoneEnable || drawProjectAreaEnable) && (
@@ -173,8 +175,6 @@ const MapSection = ({ }, }} /> - - ); }; diff --git a/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx b/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx index dd34666e..317b0eb4 100644 --- a/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx +++ b/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx @@ -99,6 +99,8 @@ const MapSection = () => { height: '100%', }} > + + {taskWayPoints && ( <> {/* render line */} @@ -182,8 +184,6 @@ const MapSection = () => { hideButton getCoordOnProperties /> - -
diff --git a/src/frontend/src/components/Projects/MapSection/index.tsx b/src/frontend/src/components/Projects/MapSection/index.tsx index b769d2bb..3daf2530 100644 --- a/src/frontend/src/components/Projects/MapSection/index.tsx +++ b/src/frontend/src/components/Projects/MapSection/index.tsx @@ -51,6 +51,8 @@ const ProjectsMapSection = () => { height: '36.375rem', }} > + + { }, }} /> */} - - ); }; From 7c8e1cd23c56d5ea4ff0991e37be991ed057dc5c Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 10:25:30 +0545 Subject: [PATCH 10/20] feat(project-creation): add map image on payload and set loading state true while capturing image --- .../CreateProject/CreateprojectLayout/index.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/components/CreateProject/CreateprojectLayout/index.tsx b/src/frontend/src/components/CreateProject/CreateprojectLayout/index.tsx index d9dec7ce..00852b06 100644 --- a/src/frontend/src/components/CreateProject/CreateprojectLayout/index.tsx +++ b/src/frontend/src/components/CreateProject/CreateprojectLayout/index.tsx @@ -80,6 +80,12 @@ const CreateprojectLayout = () => { const measurementType = useTypedSelector( state => state.createproject.measurementType, ); + const projectImage = useTypedSelector( + state => state.createproject.projectMapImage, + ); + const capturedProjectMap = useTypedSelector( + state => state.createproject.capturedProjectMap, + ); const initialState: FieldValues = { name: '', @@ -202,6 +208,7 @@ const CreateprojectLayout = () => { } if (activeStep === 4 && !splitGeojson) return; + if (activeStep !== 5) { dispatch(setCreateProjectState({ activeStep: activeStep + 1 })); return; @@ -225,6 +232,8 @@ const CreateprojectLayout = () => { // make form data with value JSON stringify to combine value on single json / form data with only 2 keys (backend didn't found project_info on non-stringified data) const formData = new FormData(); formData.append('project_info', JSON.stringify({ ...refactoredData })); + formData.append('image', projectImage.projectMapImage); + if (isTerrainFollow) { formData.append('dem', data?.dem?.[0]?.file); } @@ -265,7 +274,8 @@ const CreateprojectLayout = () => { className="!naxatw-bg-red !naxatw-text-white" rightIcon="chevron_right" withLoader - isLoading={isLoading || isCreatingProject} + isLoading={isLoading || isCreatingProject || !capturedProjectMap} + disabled={isLoading || isCreatingProject || !capturedProjectMap} > {activeStep === 5 ? 'Save' : 'Next'} From 8cbcf242a6142ad61fe49f269cee7fe9b9793c7b Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 10:28:05 +0545 Subject: [PATCH 11/20] feat(project-creartion): clear split geojson field and captured image state to false before task spliting api response --- .../CreateProject/FormContents/GenerateTask/index.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/frontend/src/components/CreateProject/FormContents/GenerateTask/index.tsx b/src/frontend/src/components/CreateProject/FormContents/GenerateTask/index.tsx index b2bfd624..6f1a015c 100644 --- a/src/frontend/src/components/CreateProject/FormContents/GenerateTask/index.tsx +++ b/src/frontend/src/components/CreateProject/FormContents/GenerateTask/index.tsx @@ -67,6 +67,12 @@ export default function GenerateTask({ formProps }: { formProps: any }) { className="naxatw-mt-4 naxatw-bg-red" onClick={() => { if (!projectArea) return; + dispatch( + setCreateProjectState({ + splitGeojson: null, + capturedProjectMap: false, + }), + ); mutate(payload); }} > From a52e94708b1c9351fca144493d3f6110d725c0ff Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 10:30:42 +0545 Subject: [PATCH 12/20] feat(project-creation): capture map section and save as a file on redux state --- .../GenerateTask/MapSection/index.tsx | 49 +++++++++++++++++-- .../src/store/actions/createproject.ts | 7 ++- .../src/store/slices/createproject.ts | 13 +++++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/frontend/src/components/CreateProject/FormContents/GenerateTask/MapSection/index.tsx b/src/frontend/src/components/CreateProject/FormContents/GenerateTask/MapSection/index.tsx index b516846a..fa92d45a 100644 --- a/src/frontend/src/components/CreateProject/FormContents/GenerateTask/MapSection/index.tsx +++ b/src/frontend/src/components/CreateProject/FormContents/GenerateTask/MapSection/index.tsx @@ -1,4 +1,4 @@ -import { useEffect } from 'react'; +import { useCallback, useEffect } from 'react'; import { useTypedSelector } from '@Store/hooks'; import { LngLatBoundsLike, Map } from 'maplibre-gl'; import { useMapLibreGLMap } from '@Components/common/MapLibreComponents'; @@ -9,13 +9,20 @@ import { GeojsonType } from '@Components/common/MapLibreComponents/types'; import getBbox from '@turf/bbox'; import { FeatureCollection } from 'geojson'; import hasErrorBoundary from '@Utils/hasErrorBoundary'; +import { useTypedDispatch } from '@UserModule/store/hooks'; +import { + saveProjectImageFile, + setCreateProjectState, +} from '@Store/actions/createproject'; const MapSection = () => { + const dispatch = useTypedDispatch(); const { map, isMapLoaded } = useMapLibreGLMap({ mapOptions: { zoom: 5, center: [84.124, 28.3949], maxZoom: 19, + preserveDrawingBuffer: true, }, disableRotation: true, }); @@ -26,6 +33,9 @@ const MapSection = () => { const splitGeojson = useTypedSelector( state => state.createproject.splitGeojson, ); + const capturedProjectMap = useTypedSelector( + state => state.createproject.capturedProjectMap, + ); useEffect(() => { if (!projectArea) return; @@ -33,6 +43,40 @@ const MapSection = () => { map?.fitBounds(bbox as LngLatBoundsLike, { padding: 25 }); }, [map, projectArea]); + // eslint-disable-next-line no-unused-vars + const takeScreenshot = useCallback(async () => { + if (!map || !isMapLoaded || !splitGeojson) return; + // const data = map.getCanvas().toDataURL('image/jpeg', 0.95); + map.getCanvas().toBlob( + (blob: any) => { + const file = new File([blob], 'project.png', { type: blob.type }); + dispatch( + saveProjectImageFile({ + projectMapImage: file, + }), + ); + dispatch( + setCreateProjectState({ + capturedProjectMap: true, + }), + ); + }, + 'image/png', + 0.95, + ); + }, [map, dispatch, isMapLoaded, splitGeojson]); + + useEffect(() => { + if (!map || !isMapLoaded || !splitGeojson || capturedProjectMap) + return () => {}; + // wait 1sec for split geojson is loaded and visible on map and capture + const captureTimeout = setTimeout(() => { + takeScreenshot(); + }, 1000); + + return () => clearTimeout(captureTimeout); + }, [map, takeScreenshot, isMapLoaded, splitGeojson, capturedProjectMap]); + return ( { height: '448px', }} > + {!splitGeojson && ( { type: 'fill', paint: { 'fill-color': '#328ffd', - 'fill-outline-color': '#D33A38', 'fill-opacity': 0.2, }, }} /> - ); }; diff --git a/src/frontend/src/store/actions/createproject.ts b/src/frontend/src/store/actions/createproject.ts index 78a71935..19231fbe 100644 --- a/src/frontend/src/store/actions/createproject.ts +++ b/src/frontend/src/store/actions/createproject.ts @@ -1,5 +1,8 @@ /* eslint-disable import/prefer-default-export */ import { createProjectSlice } from '@Store/slices/createproject'; -export const { setCreateProjectState, resetUploadedAndDrawnAreas } = - createProjectSlice.actions; +export const { + setCreateProjectState, + resetUploadedAndDrawnAreas, + saveProjectImageFile, +} = createProjectSlice.actions; diff --git a/src/frontend/src/store/slices/createproject.ts b/src/frontend/src/store/slices/createproject.ts index abf0f070..4eae0b36 100644 --- a/src/frontend/src/store/slices/createproject.ts +++ b/src/frontend/src/store/slices/createproject.ts @@ -20,6 +20,8 @@ export interface CreateProjectState { splitGeojson: Record | null; isTerrainFollow: boolean; requireApprovalFromManagerForLocking: string; + capturedProjectMap: boolean; + projectMapImage: any; } const initialState: CreateProjectState = { @@ -39,6 +41,8 @@ const initialState: CreateProjectState = { splitGeojson: null, isTerrainFollow: false, requireApprovalFromManagerForLocking: 'not_required', + capturedProjectMap: true, + projectMapImage: null, }; const setCreateProjectState: CaseReducer< @@ -49,6 +53,14 @@ const setCreateProjectState: CaseReducer< ...action.payload, }); +const saveProjectImageFile: CaseReducer< + CreateProjectState, + PayloadAction> +> = (state, action) => ({ + ...state, + projectMapImage: action.payload, +}); + const resetUploadedAndDrawnAreas: CaseReducer = state => ({ ...state, isNoflyzonePresent: initialState.isNoflyzonePresent, @@ -66,6 +78,7 @@ const createProjectSlice = createSlice({ initialState, reducers: { setCreateProjectState, + saveProjectImageFile, resetUploadedAndDrawnAreas, }, }); From 5a4b832460713250bff466865000ae3671799e34 Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 10:34:09 +0545 Subject: [PATCH 13/20] feat(project-creation): add new line typed layer on generate task to customize tasks outline style --- .../FormContents/GenerateTask/MapSection/index.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/frontend/src/components/CreateProject/FormContents/GenerateTask/MapSection/index.tsx b/src/frontend/src/components/CreateProject/FormContents/GenerateTask/MapSection/index.tsx index fa92d45a..70943a54 100644 --- a/src/frontend/src/components/CreateProject/FormContents/GenerateTask/MapSection/index.tsx +++ b/src/frontend/src/components/CreateProject/FormContents/GenerateTask/MapSection/index.tsx @@ -118,6 +118,20 @@ const MapSection = () => { }, }} /> + ); }; From d5e00b9d8478bdfd51491725f276f1636234e77f Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 13:36:03 +0545 Subject: [PATCH 14/20] style(project-dashboard): update layout-structure/UI and make responsive --- .../components/Projects/MapSection/index.tsx | 4 +- .../Projects/ProjectCardSkeleton/index.tsx | 2 +- src/frontend/src/views/Projects/index.tsx | 71 +++++++++---------- 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/src/frontend/src/components/Projects/MapSection/index.tsx b/src/frontend/src/components/Projects/MapSection/index.tsx index 3daf2530..b3f67da3 100644 --- a/src/frontend/src/components/Projects/MapSection/index.tsx +++ b/src/frontend/src/components/Projects/MapSection/index.tsx @@ -47,8 +47,8 @@ const ProjectsMapSection = () => { isMapLoaded={isMapLoaded} containerId="dashboard-map" style={{ - width: '55%', - height: '36.375rem', + width: '100%', + height: '100%', }} > diff --git a/src/frontend/src/components/Projects/ProjectCardSkeleton/index.tsx b/src/frontend/src/components/Projects/ProjectCardSkeleton/index.tsx index 2971d844..8011179a 100644 --- a/src/frontend/src/components/Projects/ProjectCardSkeleton/index.tsx +++ b/src/frontend/src/components/Projects/ProjectCardSkeleton/index.tsx @@ -2,7 +2,7 @@ import Skeleton from '@Components/RadixComponents/Skeleton'; export default function ProjectCardSkeleton() { return ( - + diff --git a/src/frontend/src/views/Projects/index.tsx b/src/frontend/src/views/Projects/index.tsx index 7fa7458d..eeb8cc06 100644 --- a/src/frontend/src/views/Projects/index.tsx +++ b/src/frontend/src/views/Projects/index.tsx @@ -12,55 +12,50 @@ import hasErrorBoundary from '@Utils/hasErrorBoundary'; const Projects = () => { const showMap = useTypedSelector(state => state.common.showMap); - // fetch api for projectsList const { data: projectsList, isLoading } = useGetProjectsListQuery(); const { data: userDetails } = useGetUserDetailsQuery(); - - const userDetailsx = getLocalStorageValue('userprofile'); + const localStorageUserDetails = getLocalStorageValue('userprofile'); useEffect(() => { - if (!userDetails || !userDetailsx) return; + if (!userDetails || !localStorageUserDetails) return; const userDetailsString = JSON.stringify(userDetails); localStorage.setItem('userprofile', userDetailsString as string); - }, [userDetails, userDetailsx]); + }, [userDetails, localStorageUserDetails]); return ( -
+
-
-
-
- {isLoading ? ( - <> - {Array.from({ length: 6 }, (_, index) => ( - - ))} - - ) : ( - (projectsList as Record[])?.map( - (singleproject: Record) => ( - - ), - ) - )} -
+
+
+ {isLoading ? ( + <> + {Array.from({ length: 8 }, (_, index) => ( + + ))} + + ) : ( + (projectsList as Record[])?.map( + (project: Record) => ( + + ), + ) + )}
- {showMap && } + {showMap && ( +
+ +
+ )}
); From 3245959fffd522b7ca9d67b5b02cb9594daaa33e Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 14:12:13 +0545 Subject: [PATCH 15/20] feat(project-dashboard-card): refactor card UI styling and add project image --- .../components/Projects/ProjectCard/index.tsx | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/frontend/src/components/Projects/ProjectCard/index.tsx b/src/frontend/src/components/Projects/ProjectCard/index.tsx index bbc38409..1e67f1e4 100644 --- a/src/frontend/src/components/Projects/ProjectCard/index.tsx +++ b/src/frontend/src/components/Projects/ProjectCard/index.tsx @@ -1,26 +1,21 @@ import { useNavigate } from 'react-router-dom'; -// import { GeojsonType } from '@Components/common/MapLibreComponents/types'; -// import MapSection from './MapSection'; interface IProjectCardProps { - // containerId: string; id: number; title: string; description: string; - // geojson: GeojsonType; slug: string; + imageUrl: string | null; } export default function ProjectCard({ - // containerId, id, title, description, - // geojson, slug, + imageUrl, }: IProjectCardProps) { const navigate = useNavigate(); - const onProjectCardClick = () => { navigate(`/projects/${id}`); }; @@ -29,12 +24,28 @@ export default function ProjectCard({
- {/* */} -

{slug}

-

{title}

-

{description}

+

+ {imageUrl ? ( + project-boundary + ) : ( + + image + + )} +

+

+ {slug} +

+

+ {title} +

+

{description}

); } From 2cde0043c24926e8fc52556c3f6861e4d5b38bd7 Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 16:42:16 +0545 Subject: [PATCH 16/20] feat(task-description): add base layer switcher and navigate to current user location button --- .../src/components/DroneOperatorTask/MapSection/index.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx b/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx index 317b0eb4..f88259fc 100644 --- a/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx +++ b/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx @@ -7,7 +7,6 @@ import { useGetTaskWaypointQuery } from '@Api/tasks'; import getBbox from '@turf/bbox'; import { coordAll } from '@turf/meta'; import { useMapLibreGLMap } from '@Components/common/MapLibreComponents'; -import BaseLayerSwitcher from '@Components/common/MapLibreComponents/BaseLayerSwitcher'; import VectorLayer from '@Components/common/MapLibreComponents/Layers/VectorLayer'; import MapContainer from '@Components/common/MapLibreComponents/MapContainer'; import { GeojsonType } from '@Components/common/MapLibreComponents/types'; @@ -15,6 +14,8 @@ import right from '@Assets/images/rightArrow.png'; import marker from '@Assets/images/marker.png'; import hasErrorBoundary from '@Utils/hasErrorBoundary'; import AsyncPopup from '@Components/common/MapLibreComponents/AsyncPopup'; +import BaseLayerSwitcherUI from '@Components/common/BaseLayerSwitcher'; +import LocateUser from '@Components/common/MapLibreComponents/LocateUser'; const MapSection = () => { const { projectId, taskId } = useParams(); @@ -99,7 +100,8 @@ const MapSection = () => { height: '100%', }} > - + + {taskWayPoints && ( <> From 7f1f916c6e7bb99f4e53d36f7465ee541da6736b Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 16:43:57 +0545 Subject: [PATCH 17/20] feat(project-creation): add base layer switcher and navigate to current user location button on AOI fill up step --- .../FormContents/DefineAOI/MapSection/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/components/CreateProject/FormContents/DefineAOI/MapSection/index.tsx b/src/frontend/src/components/CreateProject/FormContents/DefineAOI/MapSection/index.tsx index 85420c10..d6990a64 100644 --- a/src/frontend/src/components/CreateProject/FormContents/DefineAOI/MapSection/index.tsx +++ b/src/frontend/src/components/CreateProject/FormContents/DefineAOI/MapSection/index.tsx @@ -13,6 +13,8 @@ import useDrawTool from '@Components/common/MapLibreComponents/useDrawTool'; import { drawStyles } from '@Constants/map'; import { setCreateProjectState } from '@Store/actions/createproject'; import hasErrorBoundary from '@Utils/hasErrorBoundary'; +import BaseLayerSwitcherUI from '@Components/common/BaseLayerSwitcher'; +import LocateUser from '@Components/common/MapLibreComponents/LocateUser'; const MapSection = ({ onResetButtonClick, @@ -104,7 +106,8 @@ const MapSection = ({ position: 'relative', }} > - + + {(drawNoFlyZoneEnable || drawProjectAreaEnable) && (
From 1c883b6522440ab3cdbc7dfe1f4140c6cae87277 Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 17:40:14 +0545 Subject: [PATCH 18/20] feat(project-creation): add static form description --- .../Contributions/index.tsx | 15 ++-- .../DescriptionContents/DefineAOI/index.tsx | 15 ++-- .../GenerateTask/index.tsx | 6 +- .../KeyParameters/index.tsx | 27 ++++--- src/frontend/src/constants/createProject.tsx | 73 ++++++++++++++++++- 5 files changed, 102 insertions(+), 34 deletions(-) diff --git a/src/frontend/src/components/CreateProject/DescriptionContents/Contributions/index.tsx b/src/frontend/src/components/CreateProject/DescriptionContents/Contributions/index.tsx index 80532c35..3dad442c 100644 --- a/src/frontend/src/components/CreateProject/DescriptionContents/Contributions/index.tsx +++ b/src/frontend/src/components/CreateProject/DescriptionContents/Contributions/index.tsx @@ -1,11 +1,10 @@ +import { contributionsInfo } from '@Constants/createProject'; + export default function Contributions() { - return ( -
-

Conditions for Contributions

-

- Fill in your project basic information such as name, description, - hashtag, etc. -

+ return contributionsInfo?.map(info => ( +
+

{info.key}

+

{info.description}

- ); + )); } diff --git a/src/frontend/src/components/CreateProject/DescriptionContents/DefineAOI/index.tsx b/src/frontend/src/components/CreateProject/DescriptionContents/DefineAOI/index.tsx index 5cfe0d24..1ec99fa5 100644 --- a/src/frontend/src/components/CreateProject/DescriptionContents/DefineAOI/index.tsx +++ b/src/frontend/src/components/CreateProject/DescriptionContents/DefineAOI/index.tsx @@ -1,11 +1,10 @@ +import { DefineAOIInfo } from '@Constants/createProject'; + export default function DefineAOI() { - return ( -
-

Define Area Of Interest (AOI)

-

- Fill in your project basic information such as name, description, - hashtag, etc. -

+ return DefineAOIInfo?.map(info => ( +
+

{info.key}

+

{info.description}

- ); + )); } diff --git a/src/frontend/src/components/CreateProject/DescriptionContents/GenerateTask/index.tsx b/src/frontend/src/components/CreateProject/DescriptionContents/GenerateTask/index.tsx index 684817d6..becbab36 100644 --- a/src/frontend/src/components/CreateProject/DescriptionContents/GenerateTask/index.tsx +++ b/src/frontend/src/components/CreateProject/DescriptionContents/GenerateTask/index.tsx @@ -1,10 +1,10 @@ export default function GenerateTask() { return (
-

Conditions for Contributions

+

Generate task

- Fill in your project basic information such as name, description, - hashtag, etc. + Split the task into smaller chunks based on the given dimensions to + ensure more efficient and precise data collection and analysis.

); diff --git a/src/frontend/src/components/CreateProject/DescriptionContents/KeyParameters/index.tsx b/src/frontend/src/components/CreateProject/DescriptionContents/KeyParameters/index.tsx index 31ddb63c..99999db0 100644 --- a/src/frontend/src/components/CreateProject/DescriptionContents/KeyParameters/index.tsx +++ b/src/frontend/src/components/CreateProject/DescriptionContents/KeyParameters/index.tsx @@ -1,23 +1,26 @@ import { useTypedSelector } from '@Store/hooks'; import { FlexColumn, FlexRow } from '@Components/common/Layouts'; -import { keyParamsDescriptions } from '@Constants/createProject'; +import { + keyParametersInfo, + keyParamsDescriptions, +} from '@Constants/createProject'; export default function KeyParameters() { const keyParamOption = useTypedSelector( state => state.createproject.keyParamOption, ); + return ( - <> +
{keyParamOption === 'basic' ? ( -
-

- Ground Sampling Distance (meter) -

-

- Fill in your project basic information such as name, description, - hashtag, etc. -

-
+ keyParametersInfo?.map(info => ( +
+

{info.key}

+

+ {info.description} +

+
+ )) ) : ( {keyParamsDescriptions.map(desc => ( @@ -31,6 +34,6 @@ export default function KeyParameters() { ))} )} - +
); } diff --git a/src/frontend/src/constants/createProject.tsx b/src/frontend/src/constants/createProject.tsx index 9ac58d08..010facf1 100644 --- a/src/frontend/src/constants/createProject.tsx +++ b/src/frontend/src/constants/createProject.tsx @@ -16,15 +16,15 @@ import DTMIcon from '@Assets/images/DTM-Icon.svg'; import DSMIcon from '@Assets/images/DSM-icon.svg'; export type StepComponentMap = { - [key: number]: React.FC; + [key: number]: any; }; export const stepDescriptionComponents: StepComponentMap = { 1: BasicInformation, 2: DefineAOI, 3: KeyParameters, - 4: Contributions, - 5: GenerateTask, + 4: GenerateTask, + 5: Contributions, }; export const stepSwticherData = [ @@ -187,3 +187,70 @@ export const measurementTypeOptions = [ label: 'Altitude', }, ]; + +export const contributionsInfo = [ + { + key: 'Instructions for Drone Operators', + description: 'Detailed instructions or parameters for the drone operation.', + }, + { + key: 'Approval for task lock', + description: + 'Approval required tasks should be approved from project creator to proceed the mapping.', + }, +]; + +export const DefineAOIInfo = [ + { + key: 'Project Area', + description: 'Boundary of a project', + }, + { + key: 'No-fly-zone', + description: 'GEO zones that prohibit flight', + }, +]; + +export const keyParametersInfo = [ + { + key: 'Ground Sampling Distance (GSD)', + description: + 'GSD in a digital photo of the ground from air is the distance between pixel centers measured on the ground.', + }, + { + key: 'Altitude', + description: + 'The altitude at which the drone should fly during the mission, in meters.', + }, + { + key: 'Front Overlap', + description: + 'The percentage of overlap between consecutive images taken in the forward direction.', + }, + + { + key: 'Side Overlap', + description: + 'The percentage of overlap between images captured on adjacent flight lines', + }, + { + key: '2D Orthophoto/Orthophotograph', + description: + '2D orthophoto is a geometrically corrected aerial image that can be used as a map with consistent scale and accurate measurements.', + }, + { + key: 'Digital Terrain Model (DTM)', + description: + "DTM represents the bare earth surface, excluding objects and showing only the terrain's elevation", + }, + { + key: 'A Digital Surface Model (DSM)', + description: + "DSM is a 3D representation of the Earth's surface including all features like buildings and vegetation", + }, + { + key: 'DEM', + description: + 'The Digital Elevation Model (DEM) file that will be used to generate the terrain follow flight plan. This file should be in GeoTIFF format', + }, +]; From 4e3382c02ec3d43737f2ef388ddb822b597ba77b Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 19:09:30 +0545 Subject: [PATCH 19/20] feat(task-description): get `taskId` and `projectId` from url using `window.location.pathname` insted of `useParams` --- .../DescriptionSection/PopoverBox/ImageBox/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/components/DroneOperatorTask/DescriptionSection/PopoverBox/ImageBox/index.tsx b/src/frontend/src/components/DroneOperatorTask/DescriptionSection/PopoverBox/ImageBox/index.tsx index 1245e9c4..3f07475a 100644 --- a/src/frontend/src/components/DroneOperatorTask/DescriptionSection/PopoverBox/ImageBox/index.tsx +++ b/src/frontend/src/components/DroneOperatorTask/DescriptionSection/PopoverBox/ImageBox/index.tsx @@ -33,7 +33,12 @@ import PreviewImage from './PreviewImage'; const ImageBoxPopOver = () => { const dispatch = useTypedDispatch(); - const { projectId, taskId } = useParams(); + + // const { taskId, projectId } = useParams(); + + const pathname = window.location.pathname?.split('/'); + const projectId = pathname?.[2]; + const taskId = pathname?.[4]; const uploadedFilesNumber = useRef(0); const [imageObject, setImageObject] = useState([]); From d8137e54b41086ba6cb6023a0fa34367675bf3ef Mon Sep 17 00:00:00 2001 From: Sujit Date: Thu, 5 Sep 2024 19:10:07 +0545 Subject: [PATCH 20/20] feat(task-description): get `taskId` and `projectId` from url using `window.location.pathname` insted of `useParams` --- .../DescriptionSection/PopoverBox/ImageBox/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/src/components/DroneOperatorTask/DescriptionSection/PopoverBox/ImageBox/index.tsx b/src/frontend/src/components/DroneOperatorTask/DescriptionSection/PopoverBox/ImageBox/index.tsx index 3f07475a..9c5bf842 100644 --- a/src/frontend/src/components/DroneOperatorTask/DescriptionSection/PopoverBox/ImageBox/index.tsx +++ b/src/frontend/src/components/DroneOperatorTask/DescriptionSection/PopoverBox/ImageBox/index.tsx @@ -35,7 +35,6 @@ const ImageBoxPopOver = () => { const dispatch = useTypedDispatch(); // const { taskId, projectId } = useParams(); - const pathname = window.location.pathname?.split('/'); const projectId = pathname?.[2]; const taskId = pathname?.[4];