From 4e672e3c77da6edd8ae011c74f764a6f4b50187b Mon Sep 17 00:00:00 2001 From: Julian Jones Date: Sat, 14 Mar 2026 23:20:09 +0000 Subject: [PATCH 01/13] Added stateBinding variable to update when a slice state updates so checklist items are auto updated --- .../preFlightChecklistSection.jsx | 1 + gcs/src/helpers/checklistAutoBindings.js | 13 +++++ gcs/src/redux/slices/checklistSlice.js | 53 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 gcs/src/helpers/checklistAutoBindings.js diff --git a/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx b/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx index b015821dc..c1f048cc1 100644 --- a/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx +++ b/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx @@ -58,6 +58,7 @@ export default function PreFlightChecklistTab({ tabPadding }) { { checked: false, name: "Your first item, press edit to add more!", + stateBinding: "drone.connected" }, ] } diff --git a/gcs/src/helpers/checklistAutoBindings.js b/gcs/src/helpers/checklistAutoBindings.js new file mode 100644 index 000000000..2c95cb502 --- /dev/null +++ b/gcs/src/helpers/checklistAutoBindings.js @@ -0,0 +1,13 @@ +// Central registry for checklist state bindings. +// Keep a single source of truth here and derive any UI-friendly arrays from it. + +export const CHECKLIST_AUTO_BINDINGS = Object.freeze({ + DroneConnected: Object.freeze({ + key: "drone.connected", + label: "Drone Connected", + }), +}) + +export const CHECKLIST_AUTO_BINDING_OPTIONS = Object.freeze( + Object.values(CHECKLIST_AUTO_BINDINGS), +) diff --git a/gcs/src/redux/slices/checklistSlice.js b/gcs/src/redux/slices/checklistSlice.js index 869e951f3..592d6c132 100644 --- a/gcs/src/redux/slices/checklistSlice.js +++ b/gcs/src/redux/slices/checklistSlice.js @@ -1,5 +1,7 @@ import { createSelector, createSlice } from "@reduxjs/toolkit" import { v4 as uuidv4 } from "uuid" +import { CHECKLIST_AUTO_BINDINGS } from "../../helpers/checklistAutoBindings" +import { setConnected } from "./droneConnectionSlice" const checklistSlice = createSlice({ name: "checklist", @@ -44,6 +46,56 @@ const checklistSlice = createSlice({ ) } }, + setChecklistItemStateBinding: (state, action) => { + const { checklistId, itemName, stateBinding } = action.payload + const binding = stateBinding?.trim() + + state.items = state.items.map((checklist) => { + if (checklist.id !== checklistId) { + return checklist + } + + if (!Array.isArray(checklist.value)) { + return checklist + } + + return { + ...checklist, + value: checklist.value.map((valueItem) => { + if (valueItem.name !== itemName) { + return valueItem + } + + if (binding) { + return { ...valueItem, stateBinding: binding } + } + + const { stateBinding: _, ...rest } = valueItem + return rest + }), + } + }) + }, + }, + extraReducers: (builder) => { + builder.addCase(setConnected, (state, action) => { + const isConnected = action.payload + + state.items.forEach((checklist) => { + if (!Array.isArray(checklist.value)) { + return + } + + checklist.value.forEach((valueItem) => { + if ( + valueItem.stateBinding === + CHECKLIST_AUTO_BINDINGS.DroneConnected.key + ) { + valueItem.checked = isConnected + } + }) + }) + }) }, selectors: { selectChecklists: (state) => { @@ -75,6 +127,7 @@ export const { setChecklistItems, setNewChecklistName, setChecklistValueById, + setChecklistItemStateBinding, } = checklistSlice.actions export const { selectChecklists } = checklistSlice.selectors From 6cad1b25a5494e743e00bf542fa07d487cbdac49 Mon Sep 17 00:00:00 2001 From: Julian Jones Date: Sun, 15 Mar 2026 00:09:12 +0000 Subject: [PATCH 02/13] Added a simple UI, removed old HTML encoder/decoder --- .../preFlightChecklist/checkListArea.jsx | 101 +++------ .../preFlightChecklist/checkListEdit.jsx | 202 +++++++++++------- 2 files changed, 152 insertions(+), 151 deletions(-) diff --git a/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx b/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx index e195e850f..717a17ac5 100644 --- a/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx +++ b/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx @@ -3,7 +3,7 @@ */ // Native imports -import { useEffect, useState } from "react" +import { useState } from "react" // 3rd Party Imports import { ActionIcon, Button, Checkbox, Modal, Tooltip } from "@mantine/core" @@ -16,7 +16,6 @@ import { // Local Imports import EditCheckList from "./checkListEdit.jsx" -import { generateCheckListObjectFromHTMLString } from "../../../helpers/checkList.js" // Redux import { useDispatch, useSelector } from "react-redux" @@ -32,59 +31,32 @@ export default function CheckListArea({ id }) { const [showDeleteModal, setDeleteModal] = useState(false) const [editCheckListModal, setEditCheckListModal] = useState(false) - const [checkBoxListString, setCheckboxListString] = useState( - generateCheckboxListString(), - ) - const [mappedItems, setMappedItems] = useState(generateMappedItems()) const [lastToggleCheck, setLastToggleCheck] = useState(false) // false = uncheck, true = check - function generateCheckboxListString(set = false) { - // Go from list to string, returns0 - let final = "" - if (set) { - setCheckboxListString(final) + if (JSON.stringify(checklist.value) !== JSON.stringify(updated)) { + dispatch(setChecklistValueById({ id: checklist.id, value: updated })) } - return final - } - - function generateCheckboxList(defaultCheck = false) { - let final = generateCheckListObjectFromHTMLString( - checkBoxListString, - defaultCheck, - ) - dispatch(setChecklistValueById({ id: checklist.id, value: final })) - } - - function toggleCheck() { - generateCheckboxList(lastToggleCheck) setLastToggleCheck(!lastToggleCheck) } function setChecked(name, value) { - let final = [] - checkBoxListString - .split("
  • ") - .splice(1) - .forEach((element) => { - let elementName = element.split("

    ")[0].trim() - final.push({ - checked: - elementName === name - ? value - : checklist.value.find((e) => e.name === elementName).checked, - name: elementName, - }) - }) + const updated = checklist.value.map((item) => { + if (item.name !== name || item.stateBinding) { + return item + } + + return { ...item, checked: value } + }) // Check our checklist value is not the same as the updated one to stop unnecessary redux calls - if (JSON.stringify(checklist.value) !== JSON.stringify(final)) { - dispatch(setChecklistValueById({ id: checklist.id, value: final })) + if (JSON.stringify(checklist.value) !== JSON.stringify(updated)) { + dispatch(setChecklistValueById({ id: checklist.id, value: updated })) } } @@ -106,26 +78,6 @@ export default function CheckListArea({ id }) { URL.revokeObjectURL(objectUrl) } - function generateMappedItems() { - return checklist.value.map((element) => { - return ( - setChecked(element.name, !element.checked)} - /> - ) - }) - } - - useEffect(() => { - setMappedItems(generateMappedItems()) - dispatch( - setChecklistValueById({ id: checklist.id, value: checklist.value }), - ) - }, [checklist.value]) - return ( <> {/* Checkbox area */} @@ -165,18 +117,27 @@ export default function CheckListArea({ id }) { - {mappedItems} + {checklist.value.map((item, index) => ( + + setChecked(item.name, !item.checked)} + /> + + ))} {/* Edit mode */} setEditCheckListModal(false)} - checklistId={checklist.id} - checkListSet={[checkBoxListString, setCheckboxListString]} - generateCheckboxListString={generateCheckboxListString} - generateCheckboxList={generateCheckboxList} /> {/* Generic "are you sure" modal */} diff --git a/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx b/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx index 667ba721a..3d723a2e7 100644 --- a/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx +++ b/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx @@ -3,64 +3,80 @@ */ // Native Imports -import { useState } from "react" +import { useEffect, useState } from "react" // 3rd Party Imports -import { Button, Modal, TextInput } from "@mantine/core" -import { useEditor } from "@tiptap/react" -import BulletList from "@tiptap/extension-bullet-list" -import ListItem from "@tiptap/extension-list-item" -import { RichTextEditor } from "@mantine/tiptap" -import { Node } from "@tiptap/core" +import { ActionIcon, Button, Checkbox, Modal, TextInput, Select } from "@mantine/core" +import { IconPlus, IconTrashX } from "@tabler/icons-react" + +// Helpers +import { CHECKLIST_AUTO_BINDINGS } from "../../../helpers/checklistAutoBindings.js" // Redux import { useDispatch } from "react-redux" -import { setNewChecklistName } from "../../../redux/slices/checklistSlice.js" - -export default function EditCheckList({ - opened, - close, - passedName, - checklistId, - checkListSet, - generateCheckboxListString, - generateCheckboxList, -}) { +import { + setChecklistValueById, + setNewChecklistName, +} from "../../../redux/slices/checklistSlice.js" + +export default function EditCheckList({ checklist, opened, close }) { const dispatch = useDispatch() - const [name, setName] = useState(passedName) - const [checkboxList, setCheckboxList] = checkListSet - - const Document = Node.create({ - name: "doc", - topNode: true, - content: "list+", - }) - - const Paragraph = Node.create({ - name: "paragraph", - group: "block", - content: "inline*", - parseHTML() { - return [{ tag: "p" }] - }, - renderHTML({ HTMLAttributes }) { - return ["p", HTMLAttributes, 0] - }, - }) - - const Text = Node.create({ - name: "text", - group: "inline", - }) - - const editor = useEditor({ - extensions: [Document, Text, Paragraph, BulletList, ListItem], - content: checkboxList, - onUpdate: ({ editor }) => { - setCheckboxList(editor.getHTML()) - }, - autofocus: "end", - }) + const [name, setName] = useState(checklist.name) + const [items, setItems] = useState(checklist.value ?? []) + + const autoChecklistBindingsOptions = Object.values(CHECKLIST_AUTO_BINDINGS).map((item) => ({ + value: item.key, + label: item.label, + })) + + useEffect(() => { + if (!opened) { + return + } + + setName(checklist.name) + setItems(checklist.value ?? []) + }, [opened, checklist.id]) + + function updateItem(index, key, value) { + setItems((currentItems) => + currentItems.map((item, itemIndex) => { + if (itemIndex !== index) { + return item + } + + if (key === "stateBinding") { + const trimmedValue = value.trim() + return { + ...item, + stateBinding: trimmedValue === "" ? null : trimmedValue, + } + } + + return { ...item, [key]: value } + }), + ) + } + + function removeItem(index) { + setItems((currentItems) => + currentItems.filter((_, itemIndex) => itemIndex !== index), + ) + } + + function addItem() { + setItems((currentItems) => [ + ...currentItems, + { name: "", checked: false, stateBinding: null }, + ]) + } + + function handleSave(event) { + event.preventDefault() + dispatch(setNewChecklistName({ id: checklist.id, newName: name })) + dispatch(setChecklistValueById({ id: checklist.id, value: items })) + close() + } return ( -
    { - e.preventDefault() - dispatch(setNewChecklistName({ id: checklistId, newName: name })) - generateCheckboxList() - close() - }} - > -
    + +
    {/* Inputs */}

    Name

    Items

    - Bullet point list of items + Edit checklist items directly

    - - {/* - Going to keep this for future use with code blocks, no need to delete. - - - - - - */} - - - + +
    + {items.map((item, index) => ( +
    + + updateItem(index, "name", event.currentTarget.value) + } + /> + - updateItem( - index, - "stateBinding", - value - ) - } - value={item.stateBinding} + onChange={(value) => { + updateItem(index, "stateBinding", value) + updateItem(index, "checked", false) + }} + value={item.stateBinding ?? null} /> removeItem(index)} + className="self-stretch !h-auto" > @@ -149,7 +150,7 @@ export default function EditCheckList({ checklist, opened, close }) { leftSection={} onClick={addItem} type="button" - variant="subtle" + variant="light" > Add Item diff --git a/gcs/src/redux/slices/checklistSlice.js b/gcs/src/redux/slices/checklistSlice.js index 592d6c132..bfe8a592d 100644 --- a/gcs/src/redux/slices/checklistSlice.js +++ b/gcs/src/redux/slices/checklistSlice.js @@ -48,7 +48,7 @@ const checklistSlice = createSlice({ }, setChecklistItemStateBinding: (state, action) => { const { checklistId, itemName, stateBinding } = action.payload - const binding = stateBinding?.trim() + const binding = typeof stateBinding === "string" ? stateBinding.trim() : null state.items = state.items.map((checklist) => { if (checklist.id !== checklistId) { From ad76fe2819082272b4c2cad7f07abcc9d8df3716 Mon Sep 17 00:00:00 2001 From: Julian Jones Date: Sun, 15 Mar 2026 01:12:37 +0000 Subject: [PATCH 04/13] Simplified applying auto bidnings to reduce duplicate code and added armed option --- .../preFlightChecklist/checkListArea.jsx | 2 +- .../preFlightChecklist/checkListEdit.jsx | 18 +++----- gcs/src/helpers/checkList.js | 26 ------------ gcs/src/helpers/checklistAutoBindings.js | 4 ++ gcs/src/redux/slices/checklistSlice.js | 42 ++++++++++++------- 5 files changed, 38 insertions(+), 54 deletions(-) delete mode 100644 gcs/src/helpers/checkList.js diff --git a/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx b/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx index 2418f2435..ee963eba8 100644 --- a/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx +++ b/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx @@ -119,7 +119,7 @@ export default function CheckListArea({ id }) { {checklist.value.map((item, index) => (
    {/* Inputs */} -

    Name

    +

    Checklist Name

    setName(event.currentTarget.value)} /> -
    -

    Items

    -

    - Edit checklist items directly -

    -
    -
    -
    -

    Name

    +
    +

    List Item

    Auto complete?

    {items.map((item, index) => (
    updateItem(index, "name", event.currentTarget.value) } - className="col-span-2" + className="w-1/2" /> { updateItem(index, "stateBinding", value) - updateItem(index, "checked", false) + updateItem(index, "checked", false) }} value={item.stateBinding ?? null} className="grow" diff --git a/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx b/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx index c1f048cc1..5549b9372 100644 --- a/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx +++ b/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx @@ -58,7 +58,7 @@ export default function PreFlightChecklistTab({ tabPadding }) { { checked: false, name: "Your first item, press edit to add more!", - stateBinding: "drone.connected" + stateBinding: "drone.connected", }, ] } diff --git a/gcs/src/helpers/checklistAutoBindings.js b/gcs/src/helpers/checklistAutoBindings.js index 57fb75c2a..577347175 100644 --- a/gcs/src/helpers/checklistAutoBindings.js +++ b/gcs/src/helpers/checklistAutoBindings.js @@ -20,20 +20,20 @@ export const CHECKLIST_AUTO_BINDINGS = Object.freeze({ }), CompassHealthy: Object.freeze({ key: "compass.healthy", - label: "Compass Healthy" + label: "Compass Healthy", }), AccelerometerHealthy: Object.freeze({ key: "accelerometer.healthy", - label: "Accelerometer Healthy" + label: "Accelerometer Healthy", }), - // Handled in the socket middleware + // Handled in the socket middleware EkfAllGreen: Object.freeze({ key: "ekf.all.green", label: "EKF all green", }), - // For future: Look into how laptop battery could be used, this will likely be + // For future: Look into how laptop battery could be used, this will likely be // in the middleware? }) diff --git a/gcs/src/redux/slices/checklistSlice.js b/gcs/src/redux/slices/checklistSlice.js index c55fa533a..dde26a339 100644 --- a/gcs/src/redux/slices/checklistSlice.js +++ b/gcs/src/redux/slices/checklistSlice.js @@ -2,7 +2,11 @@ import { createSelector, createSlice } from "@reduxjs/toolkit" import { v4 as uuidv4 } from "uuid" import { CHECKLIST_AUTO_BINDINGS } from "../../helpers/checklistAutoBindings" import { setConnected } from "./droneConnectionSlice" -import { setEkfStatusReportData, setGpsRawIntData, setVibrationData } from "./droneInfoSlice" +import { + setEkfStatusReportData, + setGpsRawIntData, + setVibrationData, +} from "./droneInfoSlice" import { EKF_STATUS_WARNING_LEVEL } from "../../helpers/mavlinkConstants" const checklistSlice = createSlice({ @@ -50,7 +54,8 @@ const checklistSlice = createSlice({ }, setChecklistItemStateBinding: (state, action) => { const { checklistId, itemName, stateBinding } = action.payload - const binding = typeof stateBinding === "string" ? stateBinding.trim() : null + const binding = + typeof stateBinding === "string" ? stateBinding.trim() : null state.items = state.items.map((checklist) => { if (checklist.id !== checklistId) { @@ -91,39 +96,39 @@ const checklistSlice = createSlice({ action.payload, ) }), - builder.addCase(setGpsRawIntData, (state, action) => { - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.GpsSatsGt10.key, - Boolean(action.payload.satellites_visible > 10) - ) + builder.addCase(setGpsRawIntData, (state, action) => { + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.GpsSatsGt10.key, + Boolean(action.payload.satellites_visible > 10), + ) - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.GpsHdopLt1.key, - Boolean(action.payload.hdop < 1) - ) + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.GpsHdopLt1.key, + Boolean(action.payload.hdop < 1), + ) - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.GpsFixGte3.key, - Boolean(action.payload.fixType >= 3) - ) - }), - builder.addCase(setEkfStatusReportData, (state, action) => { - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.CompassHealthy.key, - Boolean(action.payload.compass_variance <= EKF_STATUS_WARNING_LEVEL) - ) - }), - builder.addCase(setVibrationData, (state, action) => { - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.AccelerometerHealthy.key, - Boolean(action.payload < 30) // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station - ) - }) + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.GpsFixGte3.key, + Boolean(action.payload.fixType >= 3), + ) + }), + builder.addCase(setEkfStatusReportData, (state, action) => { + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.CompassHealthy.key, + Boolean(action.payload.compass_variance <= EKF_STATUS_WARNING_LEVEL), + ) + }), + builder.addCase(setVibrationData, (state, action) => { + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.AccelerometerHealthy.key, + Boolean(action.payload < 30), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station + ) + }) }, selectors: { selectChecklists: (state) => { From e64fdd5b7788bdabcf47e992878cbb8bb478e3b7 Mon Sep 17 00:00:00 2001 From: Julian Jones Date: Sun, 22 Mar 2026 20:31:33 +0000 Subject: [PATCH 07/13] formatted --- gcs/src/redux/slices/checklistSlice.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcs/src/redux/slices/checklistSlice.js b/gcs/src/redux/slices/checklistSlice.js index dde26a339..043e9513b 100644 --- a/gcs/src/redux/slices/checklistSlice.js +++ b/gcs/src/redux/slices/checklistSlice.js @@ -77,7 +77,8 @@ const checklistSlice = createSlice({ return { ...valueItem, stateBinding: binding } } - const { stateBinding: _, ...rest } = valueItem + const rest = { ...valueItem } + delete rest.stateBinding return rest }), } From b8a4a445103087dfb4617e31d9493ea76a4f6795 Mon Sep 17 00:00:00 2001 From: Julian Jones Date: Sun, 22 Mar 2026 20:37:55 +0000 Subject: [PATCH 08/13] Fixed copilot suggestions --- .../tabsSectionTabs/preFlightChecklistSection.jsx | 2 +- gcs/src/redux/slices/checklistSlice.js | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx b/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx index 5549b9372..5d35e8b59 100644 --- a/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx +++ b/gcs/src/components/dashboard/tabsSectionTabs/preFlightChecklistSection.jsx @@ -58,7 +58,7 @@ export default function PreFlightChecklistTab({ tabPadding }) { { checked: false, name: "Your first item, press edit to add more!", - stateBinding: "drone.connected", + stateBinding: null, }, ] } diff --git a/gcs/src/redux/slices/checklistSlice.js b/gcs/src/redux/slices/checklistSlice.js index 043e9513b..9858380e5 100644 --- a/gcs/src/redux/slices/checklistSlice.js +++ b/gcs/src/redux/slices/checklistSlice.js @@ -107,13 +107,13 @@ const checklistSlice = createSlice({ applyAutoBinding( state, CHECKLIST_AUTO_BINDINGS.GpsHdopLt1.key, - Boolean(action.payload.hdop < 1), + Boolean(action.payload.hdop != null && action.payload.hdop < 1), ) applyAutoBinding( state, CHECKLIST_AUTO_BINDINGS.GpsFixGte3.key, - Boolean(action.payload.fixType >= 3), + Boolean(action.payload.fix_type >= 3), ) }), builder.addCase(setEkfStatusReportData, (state, action) => { @@ -124,10 +124,17 @@ const checklistSlice = createSlice({ ) }), builder.addCase(setVibrationData, (state, action) => { + const { vibration_x, vibration_y, vibration_z } = action.payload || {} + const vibrationMetric = Math.max( + Math.abs(vibration_x ?? 0), + Math.abs(vibration_y ?? 0), + Math.abs(vibration_z ?? 0), + ) + applyAutoBinding( state, CHECKLIST_AUTO_BINDINGS.AccelerometerHealthy.key, - Boolean(action.payload < 30), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station + Boolean(vibrationMetric < 30), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station ) }) }, From 0563d7734b91381e0705daae88861cddc2ebc8e0 Mon Sep 17 00:00:00 2001 From: Julian Jones Date: Sun, 22 Mar 2026 20:38:17 +0000 Subject: [PATCH 09/13] Formatted --- gcs/src/redux/middleware/socketMiddleware.js | 2 +- gcs/src/redux/slices/checklistSlice.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gcs/src/redux/middleware/socketMiddleware.js b/gcs/src/redux/middleware/socketMiddleware.js index 5e2c9954e..d5e3269b6 100644 --- a/gcs/src/redux/middleware/socketMiddleware.js +++ b/gcs/src/redux/middleware/socketMiddleware.js @@ -149,7 +149,7 @@ import { setShownParams, updateParamValue, } from "../slices/paramsSlice.js" -import { pushMessage, resetMessages } from "../slices/statusTextSlice.js" +import { pushMessage } from "../slices/statusTextSlice.js" import { setChecklistAutoBindingChecked } from "../slices/checklistSlice" import { handleEmitters } from "./emitters.js" diff --git a/gcs/src/redux/slices/checklistSlice.js b/gcs/src/redux/slices/checklistSlice.js index 9858380e5..1751c5a64 100644 --- a/gcs/src/redux/slices/checklistSlice.js +++ b/gcs/src/redux/slices/checklistSlice.js @@ -130,11 +130,11 @@ const checklistSlice = createSlice({ Math.abs(vibration_y ?? 0), Math.abs(vibration_z ?? 0), ) - + applyAutoBinding( state, CHECKLIST_AUTO_BINDINGS.AccelerometerHealthy.key, - Boolean(vibrationMetric < 30), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station + Boolean(vibrationMetric < 30), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station ) }) }, From 730ecc430ac335d3032e4635de4bb0bffedd8991 Mon Sep 17 00:00:00 2001 From: Julian Jones <37962677+NexInfinite@users.noreply.github.com> Date: Sun, 22 Mar 2026 20:43:22 +0000 Subject: [PATCH 10/13] Update gcs/src/redux/slices/checklistSlice.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- gcs/src/redux/slices/checklistSlice.js | 76 +++++++++++++------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/gcs/src/redux/slices/checklistSlice.js b/gcs/src/redux/slices/checklistSlice.js index 1751c5a64..02446b262 100644 --- a/gcs/src/redux/slices/checklistSlice.js +++ b/gcs/src/redux/slices/checklistSlice.js @@ -96,47 +96,47 @@ const checklistSlice = createSlice({ CHECKLIST_AUTO_BINDINGS.DroneConnected.key, action.payload, ) - }), - builder.addCase(setGpsRawIntData, (state, action) => { - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.GpsSatsGt10.key, - Boolean(action.payload.satellites_visible > 10), - ) + }) + builder.addCase(setGpsRawIntData, (state, action) => { + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.GpsSatsGt10.key, + Boolean(action.payload.satellites_visible > 10), + ) - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.GpsHdopLt1.key, - Boolean(action.payload.hdop != null && action.payload.hdop < 1), - ) + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.GpsHdopLt1.key, + Boolean(action.payload.hdop != null && action.payload.hdop < 1), + ) - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.GpsFixGte3.key, - Boolean(action.payload.fix_type >= 3), - ) - }), - builder.addCase(setEkfStatusReportData, (state, action) => { - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.CompassHealthy.key, - Boolean(action.payload.compass_variance <= EKF_STATUS_WARNING_LEVEL), - ) - }), - builder.addCase(setVibrationData, (state, action) => { - const { vibration_x, vibration_y, vibration_z } = action.payload || {} - const vibrationMetric = Math.max( - Math.abs(vibration_x ?? 0), - Math.abs(vibration_y ?? 0), - Math.abs(vibration_z ?? 0), - ) + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.GpsFixGte3.key, + Boolean(action.payload.fix_type >= 3), + ) + }) + builder.addCase(setEkfStatusReportData, (state, action) => { + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.CompassHealthy.key, + Boolean(action.payload.compass_variance <= EKF_STATUS_WARNING_LEVEL), + ) + }) + builder.addCase(setVibrationData, (state, action) => { + const { vibration_x, vibration_y, vibration_z } = action.payload || {} + const vibrationMetric = Math.max( + Math.abs(vibration_x ?? 0), + Math.abs(vibration_y ?? 0), + Math.abs(vibration_z ?? 0), + ) - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.AccelerometerHealthy.key, - Boolean(vibrationMetric < 30), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station - ) - }) + applyAutoBinding( + state, + CHECKLIST_AUTO_BINDINGS.AccelerometerHealthy.key, + Boolean(vibrationMetric < 30), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station + ) + }) }, selectors: { selectChecklists: (state) => { From 2af4e50b17b85d1a0e19fccab92ac1c93bce6dba Mon Sep 17 00:00:00 2001 From: Julian Jones Date: Sun, 22 Mar 2026 20:44:27 +0000 Subject: [PATCH 11/13] Fixed hardcoded value --- gcs/src/redux/slices/checklistSlice.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcs/src/redux/slices/checklistSlice.js b/gcs/src/redux/slices/checklistSlice.js index 02446b262..82334aa38 100644 --- a/gcs/src/redux/slices/checklistSlice.js +++ b/gcs/src/redux/slices/checklistSlice.js @@ -7,7 +7,7 @@ import { setGpsRawIntData, setVibrationData, } from "./droneInfoSlice" -import { EKF_STATUS_WARNING_LEVEL } from "../../helpers/mavlinkConstants" +import { EKF_STATUS_WARNING_LEVEL, VIBE_STATUS_WARNING_LEVEL } from "../../helpers/mavlinkConstants" const checklistSlice = createSlice({ name: "checklist", @@ -134,7 +134,7 @@ const checklistSlice = createSlice({ applyAutoBinding( state, CHECKLIST_AUTO_BINDINGS.AccelerometerHealthy.key, - Boolean(vibrationMetric < 30), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station + Boolean(vibrationMetric < VIBE_STATUS_WARNING_LEVEL), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station ) }) }, From 69f9c2cda584bfdebf933e00aeec8ac9ba40e777 Mon Sep 17 00:00:00 2001 From: Julian Jones <37962677+NexInfinite@users.noreply.github.com> Date: Sun, 22 Mar 2026 20:46:05 +0000 Subject: [PATCH 12/13] Update gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../components/dashboard/preFlightChecklist/checkListEdit.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx b/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx index 345baf5d5..25de1acb7 100644 --- a/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx +++ b/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx @@ -108,7 +108,7 @@ export default function EditCheckList({ checklist, opened, close }) {

    Auto complete?

    {items.map((item, index) => ( -
    +
    From b43f3736ce977faac99fda50ff64be389f8f4682 Mon Sep 17 00:00:00 2001 From: Julian Jones Date: Sun, 22 Mar 2026 21:41:01 +0000 Subject: [PATCH 13/13] Fixed linter and removed vibe checks --- gcs/src/helpers/checklistAutoBindings.js | 8 ++++---- gcs/src/redux/slices/checklistSlice.js | 22 ++-------------------- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/gcs/src/helpers/checklistAutoBindings.js b/gcs/src/helpers/checklistAutoBindings.js index 577347175..92cff8c4d 100644 --- a/gcs/src/helpers/checklistAutoBindings.js +++ b/gcs/src/helpers/checklistAutoBindings.js @@ -22,10 +22,10 @@ export const CHECKLIST_AUTO_BINDINGS = Object.freeze({ key: "compass.healthy", label: "Compass Healthy", }), - AccelerometerHealthy: Object.freeze({ - key: "accelerometer.healthy", - label: "Accelerometer Healthy", - }), + // AccelerometerHealthy: Object.freeze({ + // key: "accelerometer.healthy", + // label: "Accelerometer Healthy", + // }), // Handled in the socket middleware EkfAllGreen: Object.freeze({ diff --git a/gcs/src/redux/slices/checklistSlice.js b/gcs/src/redux/slices/checklistSlice.js index 82334aa38..84c1f9c99 100644 --- a/gcs/src/redux/slices/checklistSlice.js +++ b/gcs/src/redux/slices/checklistSlice.js @@ -2,12 +2,8 @@ import { createSelector, createSlice } from "@reduxjs/toolkit" import { v4 as uuidv4 } from "uuid" import { CHECKLIST_AUTO_BINDINGS } from "../../helpers/checklistAutoBindings" import { setConnected } from "./droneConnectionSlice" -import { - setEkfStatusReportData, - setGpsRawIntData, - setVibrationData, -} from "./droneInfoSlice" -import { EKF_STATUS_WARNING_LEVEL, VIBE_STATUS_WARNING_LEVEL } from "../../helpers/mavlinkConstants" +import { setEkfStatusReportData, setGpsRawIntData } from "./droneInfoSlice" +import { EKF_STATUS_WARNING_LEVEL } from "../../helpers/mavlinkConstants" const checklistSlice = createSlice({ name: "checklist", @@ -123,20 +119,6 @@ const checklistSlice = createSlice({ Boolean(action.payload.compass_variance <= EKF_STATUS_WARNING_LEVEL), ) }) - builder.addCase(setVibrationData, (state, action) => { - const { vibration_x, vibration_y, vibration_z } = action.payload || {} - const vibrationMetric = Math.max( - Math.abs(vibration_x ?? 0), - Math.abs(vibration_y ?? 0), - Math.abs(vibration_z ?? 0), - ) - - applyAutoBinding( - state, - CHECKLIST_AUTO_BINDINGS.AccelerometerHealthy.key, - Boolean(vibrationMetric < VIBE_STATUS_WARNING_LEVEL), // https://ardupilot.org/copter/docs/common-measuring-vibration.html#real-time-view-in-ground-station - ) - }) }, selectors: { selectChecklists: (state) => {