fixed marker color when mission is running, saving new pos to mission when pos is amended
This commit is contained in:
@@ -4,6 +4,7 @@ import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
|
|||||||
import { useMapStore } from "_store/mapStore";
|
import { useMapStore } from "_store/mapStore";
|
||||||
import { usePannelStore } from "_store/pannelStore";
|
import { usePannelStore } from "_store/pannelStore";
|
||||||
import { MapPin, MapPinned, Radius, Ruler, Search, RulerDimensionLine, Scan } from "lucide-react";
|
import { MapPin, MapPinned, Radius, Ruler, Search, RulerDimensionLine, Scan } from "lucide-react";
|
||||||
|
import { getOsmAddress } from "querys/osm";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { Popup, useMap } from "react-leaflet";
|
import { Popup, useMap } from "react-leaflet";
|
||||||
@@ -100,43 +101,8 @@ export const ContextMenu = () => {
|
|||||||
data-tip={einsatzBtnText}
|
data-tip={einsatzBtnText}
|
||||||
style={{ transform: "translateX(-50%)" }}
|
style={{ transform: "translateX(-50%)" }}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const address = await fetch(
|
const { parsed } = await getOsmAddress(contextMenu.lat, contextMenu.lng);
|
||||||
`https://nominatim.openstreetmap.org/reverse?lat=${contextMenu.lat}&lon=${contextMenu.lng}&format=json`,
|
|
||||||
);
|
|
||||||
const data = (await address.json()) as {
|
|
||||||
address?: {
|
|
||||||
ISO3166_2_lvl4?: string;
|
|
||||||
country?: string;
|
|
||||||
country_code?: string;
|
|
||||||
county?: string;
|
|
||||||
house_number?: string;
|
|
||||||
municipality?: string;
|
|
||||||
postcode?: string;
|
|
||||||
road?: string;
|
|
||||||
state?: string;
|
|
||||||
city?: string;
|
|
||||||
town?: string;
|
|
||||||
};
|
|
||||||
display_name?: string;
|
|
||||||
importance?: number;
|
|
||||||
lat?: string;
|
|
||||||
licence?: string;
|
|
||||||
lon?: string;
|
|
||||||
name?: string;
|
|
||||||
osm_id?: number;
|
|
||||||
osm_type?: string;
|
|
||||||
place_id?: number;
|
|
||||||
place_rank?: number;
|
|
||||||
type?: string;
|
|
||||||
};
|
|
||||||
const addressObj = data.address ?? {};
|
|
||||||
const objects = await addOSMobjects();
|
const objects = await addOSMobjects();
|
||||||
const exactAddress = objects.find((object) => {
|
|
||||||
return (
|
|
||||||
object.tags["addr:street"] == addressObj.road &&
|
|
||||||
object.tags["addr:housenumber"]?.includes(addressObj.house_number ?? "")
|
|
||||||
);
|
|
||||||
});
|
|
||||||
const closestToContext = objects.reduce((prev, curr) => {
|
const closestToContext = objects.reduce((prev, curr) => {
|
||||||
const prevLat = prev.nodes?.[0]?.lat ?? 0;
|
const prevLat = prev.nodes?.[0]?.lat ?? 0;
|
||||||
const prevLon = prev.nodes?.[0]?.lon ?? 0;
|
const prevLon = prev.nodes?.[0]?.lon ?? 0;
|
||||||
@@ -160,11 +126,7 @@ export const ContextMenu = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
setMissionFormValues({
|
setMissionFormValues({
|
||||||
addressLat: contextMenu.lat,
|
...parsed,
|
||||||
addressLng: contextMenu.lng,
|
|
||||||
addressCity: addressObj.city || addressObj.town || "",
|
|
||||||
addressStreet: `${addressObj.road || "keine Straße"}, ${addressObj.house_number || "keine HN"}`,
|
|
||||||
addressZip: addressObj.postcode || "",
|
|
||||||
state: "draft",
|
state: "draft",
|
||||||
addressOSMways: [closestToContext],
|
addressOSMways: [closestToContext],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -220,7 +220,8 @@ const MissionMarker = ({ mission }: { mission: Mission }) => {
|
|||||||
|
|
||||||
const needsAction =
|
const needsAction =
|
||||||
HPGValidationRequired(mission.missionStationIds, aircrafts, mission.hpgMissionString) &&
|
HPGValidationRequired(mission.missionStationIds, aircrafts, mission.hpgMissionString) &&
|
||||||
mission.hpgValidationState !== "VALID";
|
mission.hpgValidationState !== "VALID" &&
|
||||||
|
mission.state === "draft";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ import { deleteMissionAPI, editMissionAPI, sendMissionAPI } from "querys/mission
|
|||||||
import { getConnectedAircraftsAPI } from "querys/aircrafts";
|
import { getConnectedAircraftsAPI } from "querys/aircrafts";
|
||||||
import { getStationsAPI } from "querys/stations";
|
import { getStationsAPI } from "querys/stations";
|
||||||
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
|
import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
|
||||||
|
import { HPGValidationRequired } from "helpers/hpgValidationRequired";
|
||||||
|
import { getOsmAddress } from "querys/osm";
|
||||||
|
|
||||||
const Einsatzdetails = ({
|
const Einsatzdetails = ({
|
||||||
mission,
|
mission,
|
||||||
@@ -53,6 +55,10 @@ const Einsatzdetails = ({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const { data: aircrafts } = useQuery({
|
||||||
|
queryKey: ["aircrafts"],
|
||||||
|
queryFn: getConnectedAircraftsAPI,
|
||||||
|
});
|
||||||
const sendAlertMutation = useMutation({
|
const sendAlertMutation = useMutation({
|
||||||
mutationKey: ["missions"],
|
mutationKey: ["missions"],
|
||||||
mutationFn: (id: number) => sendMissionAPI(id, {}),
|
mutationFn: (id: number) => sendMissionAPI(id, {}),
|
||||||
@@ -155,26 +161,36 @@ const Einsatzdetails = ({
|
|||||||
<Navigation size={16} /> {mission.addressStreet}
|
<Navigation size={16} /> {mission.addressStreet}
|
||||||
</p>
|
</p>
|
||||||
<p className="flex items-center gap-2">
|
<p className="flex items-center gap-2">
|
||||||
<LocateFixed size={16} /> {mission.addressZip} {mission.addressCity}
|
{mission.addressZip && mission.addressCity ? (
|
||||||
|
`${mission.addressZip} ${mission.addressCity}`
|
||||||
|
) : (
|
||||||
|
<span className="italic text-gray-400">PLZ Ort nicht angegeben</span>
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{mission.state === "draft" && (
|
{mission.state === "draft" && (
|
||||||
<div>
|
<div>
|
||||||
<div className="divider mt-0 mb-0" />
|
<div className="divider mt-0 mb-0" />
|
||||||
|
|
||||||
<div className="form-control mb-2">
|
{HPGValidationRequired(
|
||||||
<label className="flex items-center gap-2 cursor-pointer">
|
mission.missionStationIds,
|
||||||
<input
|
aircrafts,
|
||||||
type="checkbox"
|
mission.hpgMissionString,
|
||||||
className="checkbox checkbox-sm checkbox-primary"
|
) && (
|
||||||
checked={ignoreHpg}
|
<div className="form-control mb-2">
|
||||||
onChange={(e) => setIgnoreHpg(e.target.checked)}
|
<label className="flex items-center gap-2 cursor-pointer">
|
||||||
/>
|
<input
|
||||||
<span className="label-text font-semibold leading-6">
|
type="checkbox"
|
||||||
Ohne HPG-Mission alarmieren
|
className="checkbox checkbox-sm checkbox-primary"
|
||||||
</span>
|
checked={ignoreHpg}
|
||||||
</label>
|
onChange={(e) => setIgnoreHpg(e.target.checked)}
|
||||||
</div>
|
/>
|
||||||
|
<span className="label-text font-semibold leading-6">
|
||||||
|
Ohne HPG-Mission alarmieren
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="flex items-center gap-2 w-full">
|
<div className="flex items-center gap-2 w-full">
|
||||||
{(!hpgNeedsAttention || ignoreHpg) &&
|
{(!hpgNeedsAttention || ignoreHpg) &&
|
||||||
@@ -220,7 +236,23 @@ const Einsatzdetails = ({
|
|||||||
{!ignoreHpg && mission.hpgValidationState === HpgValidationState.POSITION_AMANDED && (
|
{!ignoreHpg && mission.hpgValidationState === HpgValidationState.POSITION_AMANDED && (
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-warning btn-outline flex-3"
|
className="btn btn-sm btn-warning btn-outline flex-3"
|
||||||
onClick={() => sendAlertMutation.mutate(mission.id)}
|
onClick={async () => {
|
||||||
|
const { parsed } = await getOsmAddress(
|
||||||
|
mission.hpgLocationLat || mission.addressLat,
|
||||||
|
mission.hpgLocationLng || mission.addressLng,
|
||||||
|
);
|
||||||
|
await editMissionMutation.mutateAsync({
|
||||||
|
id: mission.id,
|
||||||
|
mission: {
|
||||||
|
addressLat: mission.hpgLocationLat || mission.addressLat,
|
||||||
|
addressLng: mission.hpgLocationLng || mission.addressLng,
|
||||||
|
addressStreet: parsed.addressStreet,
|
||||||
|
addressCity: parsed.addressCity,
|
||||||
|
addressZip: parsed.addressZip,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await sendAlertMutation.mutateAsync(mission.id);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<span className="flex items-center gap-2">
|
<span className="flex items-center gap-2">
|
||||||
<BellRing size={16} /> Mit neuer Position alarmieren
|
<BellRing size={16} /> Mit neuer Position alarmieren
|
||||||
|
|||||||
51
apps/dispatch/app/querys/osm.ts
Normal file
51
apps/dispatch/app/querys/osm.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { raw } from "../../../../packages/database/generated/client/runtime/library";
|
||||||
|
|
||||||
|
export const getOsmAddress = async (lat: number, lng: number) => {
|
||||||
|
const address = await fetch(
|
||||||
|
`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lng}&format=json`,
|
||||||
|
);
|
||||||
|
const data = (await address.json()) as {
|
||||||
|
address?: {
|
||||||
|
ISO3166_2_lvl4?: string;
|
||||||
|
country?: string;
|
||||||
|
country_code?: string;
|
||||||
|
county?: string;
|
||||||
|
house_number?: string;
|
||||||
|
municipality?: string;
|
||||||
|
postcode?: string;
|
||||||
|
road?: string;
|
||||||
|
state?: string;
|
||||||
|
city?: string;
|
||||||
|
town?: string;
|
||||||
|
};
|
||||||
|
display_name?: string;
|
||||||
|
importance?: number;
|
||||||
|
lat?: string;
|
||||||
|
licence?: string;
|
||||||
|
lon?: string;
|
||||||
|
name?: string;
|
||||||
|
osm_id?: number;
|
||||||
|
osm_type?: string;
|
||||||
|
place_id?: number;
|
||||||
|
place_rank?: number;
|
||||||
|
type?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
let addressStreet = "";
|
||||||
|
if (!data.address?.road && !data.address?.house_number) {
|
||||||
|
addressStreet = "keine Straße, keine HN";
|
||||||
|
} else if (data.address?.road) {
|
||||||
|
addressStreet += data.address.road;
|
||||||
|
} else if (data.address?.house_number) {
|
||||||
|
addressStreet += data.address.house_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
raw: data,
|
||||||
|
parsed: {
|
||||||
|
addressCity: data.address?.city || data.address?.town || "",
|
||||||
|
addressStreet,
|
||||||
|
addressZip: data.address?.postcode || "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user