diff --git a/.vscode/settings.json b/.vscode/settings.json index 82c1f70ed..132492e32 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,7 @@ "falconred", "frametype", "frametypename", + "hdop", "maplibre", "maptilers", "mavutil", diff --git a/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx b/gcs/src/components/dashboard/preFlightChecklist/checkListArea.jsx index e195e850f..1cb59e727 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,28 @@ 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..25de1acb7 100644 --- a/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx +++ b/gcs/src/components/dashboard/preFlightChecklist/checkListEdit.jsx @@ -3,64 +3,82 @@ */ // 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, Modal, TextInput, Select } from "@mantine/core" +import { IconPlus, IconTrashX } from "@tabler/icons-react" + +// Helpers +import { CHECKLIST_AUTO_BINDING_OPTIONS } 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 = CHECKLIST_AUTO_BINDING_OPTIONS.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 = typeof value === "string" ? 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

    +

    Checklist Name

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

    Items

    -

    - Bullet point list of items -

    +
    +
    +

    List Item

    +

    Auto complete?

    +
    + {items.map((item, index) => ( +
    + + updateItem(index, "name", event.currentTarget.value) + } + className="w-1/2" + /> +