diff --git a/src/frontend/src/components/DroneOperatorTask/DescriptionSection/DescriptionBox/index.tsx b/src/frontend/src/components/DroneOperatorTask/DescriptionSection/DescriptionBox/index.tsx
index 23673ee9..f87c5cdc 100644
--- a/src/frontend/src/components/DroneOperatorTask/DescriptionSection/DescriptionBox/index.tsx
+++ b/src/frontend/src/components/DroneOperatorTask/DescriptionSection/DescriptionBox/index.tsx
@@ -291,42 +291,43 @@ const DescriptionBox = () => {
)}
- {taskAssetsInformation?.state === 'IMAGE_PROCESSING_FAILED' && (
-
-
+ ))}
)}
>
diff --git a/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx b/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx
index a1afa300..81ef5326 100644
--- a/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx
+++ b/src/frontend/src/components/DroneOperatorTask/MapSection/index.tsx
@@ -16,7 +16,7 @@ import LocateUser from '@Components/common/MapLibreComponents/LocateUser';
import MapContainer from '@Components/common/MapLibreComponents/MapContainer';
import { GeojsonType } from '@Components/common/MapLibreComponents/types';
import { Button } from '@Components/RadixComponents/Button';
-import { postTaskWaypoint } from '@Services/tasks';
+import { postRotatedTaskWayPoint, postTaskWaypoint } from '@Services/tasks';
import AsyncPopup from '@Components/common/MapLibreComponents/NewAsyncPopup';
import { toggleModal } from '@Store/actions/common';
import {
@@ -480,6 +480,31 @@ const MapSection = ({ className }: { className?: string }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dragging, isMapLoaded, map]);
+ const { mutate: postRotatedFlightPlan, isLoading: flighplanIsUpdating } =
+ useMutation({
+ mutationFn: postRotatedTaskWayPoint,
+ onSuccess: () => {
+ toast.success('Flight plan rotated successfully');
+ queryClient.invalidateQueries(['task-waypoints']);
+ },
+ onError: (err: any) => {
+ toast.error(err?.response?.data?.detail || err.message);
+ },
+ });
+
+ function handeSaveRotatedFlightPlan() {
+ if (!map || !isMapLoaded) return;
+ const pointsSource = map.getSource('waypoint-points');
+
+ if (pointsSource && pointsSource instanceof GeoJSONSource) {
+ const pointsData = pointsSource?._data;
+ postRotatedFlightPlan({
+ taskId,
+ data: JSON.stringify(pointsData),
+ });
+ }
+ }
+
return (
<>
{
withLoader
leftIcon="save"
className="naxatw-w-[10.8rem] naxatw-bg-red"
+ isLoading={flighplanIsUpdating}
+ disabled={rotationAngle === 0}
+ onClick={() => handeSaveRotatedFlightPlan()}
>
Save Rotated Flight Plan
{/*
- Rotated: {rotationAngle.toFixed(2)}°
-
*/}
+ Rotated: {rotationAngle.toFixed(2)}°
+ */}
diff --git a/src/frontend/src/constants/createProject.tsx b/src/frontend/src/constants/createProject.tsx
index 3c3baaad..f5cabcc2 100644
--- a/src/frontend/src/constants/createProject.tsx
+++ b/src/frontend/src/constants/createProject.tsx
@@ -321,4 +321,3 @@ export const demFileOptions = [
},
{ name: 'Upload DEM File', label: 'Upload DEM File', value: 'manual' },
];
-
diff --git a/src/frontend/src/services/tasks.ts b/src/frontend/src/services/tasks.ts
index d1bb3d2c..135e62c4 100644
--- a/src/frontend/src/services/tasks.ts
+++ b/src/frontend/src/services/tasks.ts
@@ -23,3 +23,10 @@ export const getTaskAssetsInfo = (projectId: string, taskId: string) =>
export const postProcessImagery = (projectId: string, taskId: string) =>
authenticated(api).post(`/projects/process_imagery/${projectId}/${taskId}/`);
+
+export const postRotatedTaskWayPoint = (payload: Record) => {
+ const { taskId, data } = payload;
+ return authenticated(api).post(`/waypoint/${taskId}/generate-kmz/`, data, {
+ headers: { 'Content-Type': 'application/json' },
+ });
+};