From c6f319a36f417d49b0d2fda72672819a9a43603c Mon Sep 17 00:00:00 2001 From: Kush Makkapati Date: Fri, 8 Aug 2025 02:17:21 +0100 Subject: [PATCH 01/10] Start adding fence functionality to missions --- .../components/missions/fenceItemsTable.jsx | 55 +++++++ .../missions/fenceItemsTableRow.jsx | 142 ++++++++++++++++++ gcs/src/components/missions/missionsMap.jsx | 5 +- .../components/missions/rallyItemsTable.jsx | 8 +- gcs/src/helpers/mavlinkConstants.js | 9 +- gcs/src/missions.jsx | 24 ++- 6 files changed, 229 insertions(+), 14 deletions(-) create mode 100644 gcs/src/components/missions/fenceItemsTable.jsx create mode 100644 gcs/src/components/missions/fenceItemsTableRow.jsx diff --git a/gcs/src/components/missions/fenceItemsTable.jsx b/gcs/src/components/missions/fenceItemsTable.jsx new file mode 100644 index 000000000..0037890af --- /dev/null +++ b/gcs/src/components/missions/fenceItemsTable.jsx @@ -0,0 +1,55 @@ +/* + This table displays all the fence items. +*/ + +import { Table } from "@mantine/core" +import React from "react" +import FenceItemsTableRow from "./fenceItemsTableRow" + +function FenceItemsTableNonMemo({ + fenceItems, + updateMissionItem, + deleteMissionItem, + updateMissionItemOrder, +}) { + return ( + + + + + Command + Param 1 + + + + Lat + Lng + + Frame + + + + + {fenceItems.map((fenceItem, idx) => { + return ( + + ) + })} + +
+ ) +} + +function propsAreEqual(prev, next) { + return JSON.stringify(prev) === JSON.stringify(next) +} +const FenceItemsTable = React.memo(FenceItemsTableNonMemo, propsAreEqual) + +export default FenceItemsTable diff --git a/gcs/src/components/missions/fenceItemsTableRow.jsx b/gcs/src/components/missions/fenceItemsTableRow.jsx new file mode 100644 index 000000000..c1e250370 --- /dev/null +++ b/gcs/src/components/missions/fenceItemsTableRow.jsx @@ -0,0 +1,142 @@ +/* + This component displays the row for a fence item in a table. +*/ + +import { + ActionIcon, + NumberInput, + Select, + TableTd, + TableTr, +} from "@mantine/core" +import { IconArrowDown, IconArrowUp, IconTrash } from "@tabler/icons-react" +import { useEffect, useState } from "react" +import { coordToInt, intToCoord } from "../../helpers/dataFormatters" +import { + FENCE_ITEM_COMMANDS_LIST, + MAV_FRAME_LIST, +} from "../../helpers/mavlinkConstants" + +const coordsFractionDigits = 9 + +export default function FenceItemsTableRow({ + index, + fenceItem, + updateMissionItem, + deleteMissionItem, + updateMissionItemOrder, +}) { + const [fenceItemData, setFenceItemData] = useState(fenceItem) + + useEffect(() => { + setFenceItemData(fenceItem) + }, [fenceItem]) + + useEffect(() => { + updateMissionItem(fenceItemData) + }, [fenceItemData]) + + function getDisplayCommandName(commandName) { + if (commandName.startsWith("MAV_CMD_NAV_")) { + commandName = commandName.replace("MAV_CMD_NAV_", "") + } else if (commandName.startsWith("MAV_CMD_")) { + commandName = commandName.replace("MAV_CMD_", "") + } + + return commandName + } + + function getAvailableCommands() { + var commandsList = FENCE_ITEM_COMMANDS_LIST + + return Object.entries(commandsList).map(([key, value]) => ({ + value: key, + label: getDisplayCommandName(value), + })) + } + + function getFrameName(frameId) { + var frameName = MAV_FRAME_LIST[frameId] + + if (frameName.startsWith("MAV_FRAME_")) { + frameName = frameName.replace("MAV_FRAME_", "") + } + + return frameName || "UNKNOWN" + } + + function updateFenceItemData(key, newVal) { + setFenceItemData({ + ...fenceItemData, + [key]: newVal, + }) + } + + return ( + + {index} + +