diff --git a/apps/dispatch/app/_components/map/ContextMenu.tsx b/apps/dispatch/app/_components/map/ContextMenu.tsx index 008c9175..8cb3120b 100644 --- a/apps/dispatch/app/_components/map/ContextMenu.tsx +++ b/apps/dispatch/app/_components/map/ContextMenu.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { OSMWay } from "@repo/db"; +import { OSMWay, Prisma } from "@repo/db"; import { useDispatchConnectionStore } from "_store/dispatch/connectionStore"; import { useMapStore } from "_store/mapStore"; import { usePannelStore } from "_store/pannelStore"; @@ -8,6 +8,8 @@ import { getOsmAddress } from "_querys/osm"; import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import { Popup, useMap } from "react-leaflet"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { editMissionAPI } from "_querys/missions"; export const ContextMenu = () => { const map = useMap(); @@ -19,9 +21,8 @@ export const ContextMenu = () => { setSearchPopup, toggleSearchElementSelection, } = useMapStore(); - const { missionFormValues, setMissionFormValues, setOpen, isOpen } = usePannelStore( - (state) => state, - ); + const { missionFormValues, setMissionFormValues, setOpen, isOpen, editingMissionId } = + usePannelStore((state) => state); const [showRulerOptions, setShowRulerOptions] = useState(false); const [rulerHover, setRulerHover] = useState(false); const [rulerOptionsHover, setRulerOptionsHover] = useState(false); @@ -54,7 +55,7 @@ export const ContextMenu = () => { const einsatzBtnText = missionFormValues && isOpen ? "Position übernehmen" : "Einsatz erstellen"; - const addOSMobjects = async () => { + const addOSMobjects = async (ignorePreviosSelected?: boolean) => { const res = await fetch( `https://overpass-api.de/api/interpreter?data=${encodeURIComponent(` [out:json]; @@ -73,7 +74,7 @@ export const ContextMenu = () => { .map((e: any) => { const elementInMap = searchElements.find((el) => el.wayID === e.id); return { - isSelected: elementInMap?.isSelected ?? false, + isSelected: ignorePreviosSelected ? false : (elementInMap?.isSelected ?? false), wayID: e.id, nodes: e.nodes.map((nodeId: string) => { const node = data.elements.find((element: any) => element.id === nodeId); @@ -111,7 +112,7 @@ export const ContextMenu = () => { style={{ transform: "translateX(-50%)" }} onClick={async () => { const { parsed } = await getOsmAddress(contextMenu.lat, contextMenu.lng); - const objects = await addOSMobjects(); + const objects = await addOSMobjects(true); const closestToContext = objects.reduce((prev, curr) => { const prevLat = prev.nodes?.[0]?.lat ?? 0; const prevLon = prev.nodes?.[0]?.lon ?? 0; @@ -135,10 +136,11 @@ export const ContextMenu = () => { ); if (closestToContext) { - toggleSearchElementSelection(closestToContext.wayID); + toggleSearchElementSelection(closestToContext.wayID, true); } setMissionFormValues({ + ...missionFormValues, ...parsed, state: "draft", addressLat: contextMenu.lat, diff --git a/apps/dispatch/app/_components/map/MissionMarkers.tsx b/apps/dispatch/app/_components/map/MissionMarkers.tsx index 2cf1a4a0..35fef726 100644 --- a/apps/dispatch/app/_components/map/MissionMarkers.tsx +++ b/apps/dispatch/app/_components/map/MissionMarkers.tsx @@ -1,5 +1,5 @@ import { Marker, useMap } from "react-leaflet"; -import { DivIcon, Marker as LMarker, Popup as LPopup } from "leaflet"; +import { DivIcon, LatLngExpression, Marker as LMarker, Popup as LPopup } from "leaflet"; import { useMapStore } from "_store/mapStore"; import { usePannelStore } from "_store/pannelStore"; import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react"; @@ -175,7 +175,7 @@ const MissionPopupContent = ({ hpgLocationLat: mission.hpgLocationLat ?? undefined, hpgLocationLng: mission.hpgLocationLng ?? undefined, }); - setEditingMission(true, mission.id); + setEditingMission(mission.id); setOpen(true); }} > @@ -208,6 +208,7 @@ const MissionPopupContent = ({ const MissionMarker = ({ mission }: { mission: Mission }) => { const map = useMap(); const [hideMarker, setHideMarker] = useState(false); + const { editingMissionId, missionFormValues } = usePannelStore((state) => state); const markerRef = useRef(null); const popupRef = useRef(null); @@ -329,11 +330,28 @@ const MissionMarker = ({ mission }: { mission: Mission }) => { `; }; + const markerPosition = useMemo(() => { + return [ + editingMissionId === mission.id && missionFormValues?.addressLat + ? missionFormValues.addressLat + : mission.addressLat, + editingMissionId === mission.id && missionFormValues?.addressLng + ? missionFormValues.addressLng + : mission.addressLng, + ]; + }, [ + editingMissionId, + mission.addressLat, + mission.addressLng, + missionFormValues?.addressLat, + missionFormValues?.addressLng, + ]); + return ( { }} id={`mission-${mission.id.toString()}`} ref={popupRef} - position={[mission.addressLat, mission.addressLng]} + position={markerPosition} autoClose={false} closeOnClick={false} autoPan={false} diff --git a/apps/dispatch/app/_components/map/SearchElements.tsx b/apps/dispatch/app/_components/map/SearchElements.tsx index 2724965d..24deb97f 100644 --- a/apps/dispatch/app/_components/map/SearchElements.tsx +++ b/apps/dispatch/app/_components/map/SearchElements.tsx @@ -1,5 +1,5 @@ import { useMapStore } from "_store/mapStore"; -import { Marker, Polygon, Popup } from "react-leaflet"; +import { Polygon } from "react-leaflet"; import { useQuery } from "@tanstack/react-query"; import { getMissionsAPI } from "_querys/missions"; import { usePannelStore } from "_store/pannelStore"; @@ -26,14 +26,7 @@ export const SearchElements = () => { useEffect(() => { if (pannelOpen) { - const missionEdited = missions?.find((m) => m.id === editingMissionId); - if (missionEdited) { - const elements = missionEdited.addressOSMways.map((e) => ({ - ...(e as unknown as OSMWay), - isSelected: true, - })); - setSearchElements(elements); - } + // OSM Elements wirden in ContextMenu.tsx gesetzt } else { const openMissions = openMissionMarker.map((m) => { const mission = missions?.find((mi) => mi.id === m.id); diff --git a/apps/dispatch/app/_store/mapStore.ts b/apps/dispatch/app/_store/mapStore.ts index 86d9ef48..01d308c6 100644 --- a/apps/dispatch/app/_store/mapStore.ts +++ b/apps/dispatch/app/_store/mapStore.ts @@ -26,7 +26,7 @@ export interface MapStore { }) => void; searchElements: OSMWay[]; setSearchElements: (elements: MapStore["searchElements"]) => void; - toggleSearchElementSelection: (elementId: number) => void; + toggleSearchElementSelection: (elementId: number, forceState?: boolean) => void; setContextMenu: (popup: MapStore["contextMenu"]) => void; searchPopup: { lat: number; @@ -83,11 +83,11 @@ export const useMapStore = create((set, get) => ({ set(() => ({ searchElements: elements, })), - toggleSearchElementSelection: (elementId) => { + toggleSearchElementSelection: (elementId, forceState) => { const searchElements = get().searchElements; const element = searchElements.find((e) => e.wayID === elementId); if (!element) return; - element.isSelected = !element.isSelected; + element.isSelected = forceState ? forceState : !element.isSelected; set(() => ({ searchElements: [...searchElements], })); diff --git a/apps/dispatch/app/_store/pannelStore.ts b/apps/dispatch/app/_store/pannelStore.ts index de5b53ba..ab0c5724 100644 --- a/apps/dispatch/app/_store/pannelStore.ts +++ b/apps/dispatch/app/_store/pannelStore.ts @@ -7,9 +7,8 @@ interface PannelStore { setOpen: (isOpen: boolean) => void; missionFormValues?: Partial; setMissionFormValues: (values: Partial) => void; - isEditingMission: boolean; editingMissionId: number | null; - setEditingMission: (isEditing: boolean, missionId: number | null) => void; + setEditingMission: (missionId: number | null) => void; } export const usePannelStore = create((set) => ({ @@ -17,8 +16,6 @@ export const usePannelStore = create((set) => ({ setOpen: (isOpen) => set({ isOpen }), missionFormValues: undefined, setMissionFormValues: (values) => set({ missionFormValues: values }), - isEditingMission: false, editingMissionId: null, - setEditingMission: (isEditing, missionId) => - set({ isEditingMission: isEditing, editingMissionId: missionId }), + setEditingMission: (missionId) => set({ editingMissionId: missionId }), })); diff --git a/apps/dispatch/app/dispatch/_components/pannel/MissionForm.tsx b/apps/dispatch/app/dispatch/_components/pannel/MissionForm.tsx index 483d81e7..22370230 100644 --- a/apps/dispatch/app/dispatch/_components/pannel/MissionForm.tsx +++ b/apps/dispatch/app/dispatch/_components/pannel/MissionForm.tsx @@ -30,7 +30,7 @@ import { AxiosError } from "axios"; import { cn } from "_helpers/cn"; export const MissionForm = () => { - const { isEditingMission, editingMissionId, setEditingMission } = usePannelStore(); + const { editingMissionId, setEditingMission } = usePannelStore(); const queryClient = useQueryClient(); const { setSearchElements, searchElements, setContextMenu } = useMapStore((s) => s); @@ -130,7 +130,9 @@ export const MissionForm = () => { "addressOSMways", searchElements.filter((e) => e.isSelected) as unknown as JsonValueType[], ); - }, [searchElements, form]); + }, [searchElements, form, missionFormValues]); + + console.log("addressOSMways", form.watch("addressOSMways")); useEffect(() => { if (missionFormValues) { @@ -139,6 +141,7 @@ export const MissionForm = () => { return; } for (const key in missionFormValues) { + if (key === "addressOSMways") continue; // Skip addressOSMways as it is handled separately form.setValue( key as keyof MissionOptionalDefaults, missionFormValues[key as keyof MissionOptionalDefaults], @@ -416,16 +419,17 @@ export const MissionForm = () => {
- {isEditingMission && editingMissionId ? ( + {editingMissionId ? (