Skip to content

Commit 5511e89

Browse files
Alpha 0.1.10/621 show a warning if changes were made to the mission but not written to the drone yet (#629)
* Attempt to add warning for unwritten changes * Add mission tests (#616) * Clean up mission tests * Fix bug with max slope gradient in missionStatistics * Add tests for getting specific missions * Add upload mission tests * Add unit tests for MissionController functionality * Address copilot review comments * Dashboard.jsx change for redux (#617) * Fixed store, setup sockets, and started on dashboard * Dashboard basically done * Fixed map and refactored * Cleaned up code and fixed mission items * Fixes * fixed linting * AI Fixes * Moved gps out and fixed messages - more to move still * Updated messages * More moving of variables/cleaning up * Moved more things around :D * formatted D: * Fixed drone connection issues and states * formatted * FIXED IT WOOO * formatted * Kush fixes * Fix activeTab state not updating bug (#625) * Fix activeTab state not updating bug * Move getFrameName function into dataFormatters file * Attempt to add warning for unwritten changes * Remove unused code * Remove mission_type from write_mission_result * Fix equality comparision statements --------- Co-authored-by: Julian Jones <37962677+NexInfinite@users.noreply.github.com>
1 parent 8efec3b commit 5511e89

4 files changed

Lines changed: 97 additions & 8 deletions

File tree

gcs/src/components/missions/fenceItemsTableRow.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ export default function FenceItemsTableRow({
5353
}, [fenceItem])
5454

5555
useEffect(() => {
56-
updateMissionItem(fenceItemData)
56+
if (JSON.stringify(fenceItem) !== JSON.stringify(fenceItemData)) {
57+
updateMissionItem(fenceItemData)
58+
}
5759
}, [fenceItemData])
5860

5961
function updateFenceItemData(key, newVal) {

gcs/src/components/missions/missionItemsTableRow.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ export default function MissionItemsTableRow({
3838
}, [missionItem])
3939

4040
useEffect(() => {
41-
updateMissionItem(missionItemData)
41+
if (JSON.stringify(missionItem) !== JSON.stringify(missionItemData)) {
42+
updateMissionItem(missionItemData)
43+
}
4244
}, [missionItemData])
4345

4446
function getDisplayCommandName(commandName) {

gcs/src/components/missions/rallyItemsTableRow.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ export default function RallyItemsTableRow({
3131
}, [rallyItem])
3232

3333
useEffect(() => {
34-
updateRallyItem(rallyItemData)
34+
if (JSON.stringify(rallyItem) !== JSON.stringify(rallyItemData)) {
35+
updateRallyItem(rallyItemData)
36+
}
3537
}, [rallyItemData])
3638

3739
function updateRallyItemData(key, newVal) {

gcs/src/missions.jsx

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,22 @@ const tailwindColors = resolveConfig(tailwindConfig).theme.colors
5353

5454
const coordsFractionDigits = 7
5555

56+
function UnwrittenChangesWarning({ unwrittenChanges }) {
57+
const firstUnwrittenTab = Object.entries(unwrittenChanges).find(
58+
([, changed]) => changed,
59+
)
60+
61+
return (
62+
<>
63+
{firstUnwrittenTab && (
64+
<p className="text-red-400 text-center">
65+
You have unwritten {firstUnwrittenTab[0]} changes.
66+
</p>
67+
)}
68+
</>
69+
)
70+
}
71+
5672
export default function Missions() {
5773
// Local Storage
5874
const [connected] = useSessionStorage({
@@ -68,6 +84,15 @@ export default function Missions() {
6884
// Need to keep a reference to the active tab to avoid stale closures
6985
const activeTabRef = useRef(activeTab)
7086

87+
const [unwrittenChanges, setUnwrittenChanges] = useSessionStorage({
88+
key: "unwrittenChanges",
89+
defaultValue: {
90+
mission: false,
91+
fence: false,
92+
rally: false,
93+
},
94+
})
95+
7196
// Mission data
7297
const [missionItems, setMissionItems] = useSessionStorage({
7398
key: "missionItems",
@@ -126,10 +151,6 @@ export default function Missions() {
126151
[],
127152
)
128153

129-
useEffect(() => {
130-
setActiveTab("mission") // Default to mission tab on load
131-
}, [])
132-
133154
useEffect(() => {
134155
if (!connected) {
135156
return
@@ -173,18 +194,21 @@ export default function Missions() {
173194
}
174195
updateHomePositionBasedOnWaypoints(missionItemsWithIds)
175196
setMissionItems(missionItemsWithIds)
197+
setUnwrittenChanges((prev) => ({ ...prev, mission: false }))
176198
} else if (data.mission_type === "fence") {
177199
const fenceItemsWithIds = []
178200
for (let fence of data.items) {
179201
fenceItemsWithIds.push(addIdToItem(fence))
180202
}
181203
setFenceItems(fenceItemsWithIds)
204+
setUnwrittenChanges((prev) => ({ ...prev, fence: false }))
182205
} else if (data.mission_type === "rally") {
183206
const rallyItemsWithIds = []
184207
for (let rallyItem of data.items) {
185208
rallyItemsWithIds.push(addIdToItem(rallyItem))
186209
}
187210
setRallyItems(rallyItemsWithIds)
211+
setUnwrittenChanges((prev) => ({ ...prev, rally: false }))
188212
}
189213

190214
showSuccessNotification(`${data.mission_type} read successfully`)
@@ -195,6 +219,10 @@ export default function Missions() {
195219

196220
if (data.success) {
197221
showSuccessNotification(data.message)
222+
setUnwrittenChanges((prev) => ({
223+
...prev,
224+
[activeTabRef.current]: false,
225+
}))
198226
} else {
199227
showErrorNotification(data.message)
200228
}
@@ -209,21 +237,23 @@ export default function Missions() {
209237
}
210238

211239
updateHomePositionBasedOnWaypoints(missionItemsWithIds)
212-
213240
setMissionItems(missionItemsWithIds)
241+
setUnwrittenChanges((prev) => ({ ...prev, mission: true }))
214242
} else if (data.mission_type === "fence") {
215243
const fenceItemsWithIds = []
216244
for (let fence of data.items) {
217245
fenceItemsWithIds.push(addIdToItem(fence))
218246
}
219247
setFenceItems(fenceItemsWithIds)
248+
setUnwrittenChanges((prev) => ({ ...prev, fence: true }))
220249
} else if (data.mission_type === "rally") {
221250
const rallyItemsWithIds = []
222251
for (let rallyItem of data.items) {
223252
rallyItemsWithIds.push(addIdToItem(rallyItem))
224253
}
225254

226255
setRallyItems(rallyItemsWithIds)
256+
setUnwrittenChanges((prev) => ({ ...prev, rally: true }))
227257
}
228258
showSuccessNotification(data.message)
229259
} else {
@@ -350,6 +380,11 @@ export default function Missions() {
350380

351381
setRallyItems((prevItems) => [...prevItems, newMissionItem])
352382
}
383+
384+
setUnwrittenChanges((prev) => ({
385+
...prev,
386+
[activeTabRef.current]: true,
387+
}))
353388
}
354389

355390
function createHomePositionItem() {
@@ -401,13 +436,42 @@ export default function Missions() {
401436
)
402437
}
403438

439+
function isEqualItem(newItem, itemsList) {
440+
return (
441+
JSON.stringify(itemsList.find((item) => item.id === newItem.id)) ===
442+
JSON.stringify(newItem)
443+
)
444+
}
445+
446+
// Check if the updated mission item is equal to the current mission item
447+
// if so, don't update
448+
404449
if (activeTabRef.current === "mission") {
450+
if (isEqualItem(updatedMissionItem, missionItems)) {
451+
return
452+
}
453+
405454
setMissionItems((prevItems) => getUpdatedItems(prevItems))
406455
} else if (activeTabRef.current === "fence") {
456+
if (isEqualItem(updatedMissionItem, fenceItems)) {
457+
return
458+
}
459+
407460
setFenceItems((prevItems) => getUpdatedItems(prevItems))
408461
} else if (activeTabRef.current === "rally") {
462+
if (isEqualItem(updatedMissionItem, rallyItems)) {
463+
return
464+
}
465+
409466
setRallyItems((prevItems) => getUpdatedItems(prevItems))
467+
} else {
468+
return
410469
}
470+
471+
setUnwrittenChanges((prev) => ({
472+
...prev,
473+
[activeTabRef.current]: true,
474+
}))
411475
}
412476

413477
function deleteMissionItem(missionItemId) {
@@ -427,6 +491,11 @@ export default function Missions() {
427491
} else if (activeTabRef.current === "rally") {
428492
setRallyItems((prevItems) => getUpdatedItems(prevItems))
429493
}
494+
495+
setUnwrittenChanges((prev) => ({
496+
...prev,
497+
[activeTabRef.current]: true,
498+
}))
430499
}
431500

432501
function updateMissionItemOrder(missionItemId, indexIncrement) {
@@ -464,8 +533,10 @@ export default function Missions() {
464533

465534
if (activeTabRef.current === "mission") {
466535
setMissionItems((prevItems) => updateItemOrder(prevItems))
536+
setUnwrittenChanges((prev) => ({ ...prev, mission: true }))
467537
} else if (activeTabRef.current === "fence") {
468538
setFenceItems((prevItems) => updateItemOrder(prevItems))
539+
setUnwrittenChanges((prev) => ({ ...prev, fence: true }))
469540
}
470541
}
471542

@@ -600,6 +671,8 @@ export default function Missions() {
600671
}
601672
setMissionItems((prevItems) => [newHomeMissionItem, ...prevItems])
602673
}
674+
675+
setUnwrittenChanges((prev) => ({ ...prev, mission: true }))
603676
}
604677

605678
function clearMissionItems() {
@@ -618,6 +691,11 @@ export default function Missions() {
618691
} else if (activeTabRef.current === "rally") {
619692
setRallyItems([])
620693
}
694+
695+
setUnwrittenChanges((prev) => ({
696+
...prev,
697+
[activeTabRef.current]: true,
698+
}))
621699
}
622700

623701
function addFencePolygon(newFenceItems) {
@@ -655,6 +733,7 @@ export default function Missions() {
655733
})
656734

657735
setFenceItems((prevItems) => [...prevItems, ...newFenceMissionItems])
736+
setUnwrittenChanges((prev) => ({ ...prev, fence: true }))
658737
}
659738

660739
return (
@@ -716,6 +795,10 @@ export default function Missions() {
716795
>
717796
<div className="flex flex-col gap-8 p-4">
718797
<div className="flex flex-col gap-4">
798+
<UnwrittenChangesWarning
799+
unwrittenChanges={unwrittenChanges}
800+
/>
801+
719802
<Button
720803
onClick={() => {
721804
readMissionFromDrone()

0 commit comments

Comments
 (0)