Fixed StationSelectBug, Fixed HPGNotificationGuf, see #45
This commit is contained in:
@@ -257,6 +257,9 @@ router.post("/:id/hpg-validation-result", async (req, res) => {
|
|||||||
type: "hpg-validation",
|
type: "hpg-validation",
|
||||||
status: "success",
|
status: "success",
|
||||||
message: `HPG Validierung erfolgreich`,
|
message: `HPG Validierung erfolgreich`,
|
||||||
|
data: {
|
||||||
|
mission: newMission,
|
||||||
|
},
|
||||||
} as NotificationPayload);
|
} as NotificationPayload);
|
||||||
|
|
||||||
if (result.alertWhenValid) {
|
if (result.alertWhenValid) {
|
||||||
@@ -268,6 +271,9 @@ router.post("/:id/hpg-validation-result", async (req, res) => {
|
|||||||
type: "hpg-validation",
|
type: "hpg-validation",
|
||||||
status: "failed",
|
status: "failed",
|
||||||
message: result.state,
|
message: result.state,
|
||||||
|
data: {
|
||||||
|
mission: newMission,
|
||||||
|
},
|
||||||
} as NotificationPayload);
|
} as NotificationPayload);
|
||||||
}
|
}
|
||||||
res.json({
|
res.json({
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import { Select } from "_components/Select";
|
|||||||
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
|
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
|
||||||
import { getStationsAPI } from "_querys/stations";
|
import { getStationsAPI } from "_querys/stations";
|
||||||
import { Ambulance, FireExtinguisher, Radio, Siren } from "lucide-react";
|
import { Ambulance, FireExtinguisher, Radio, Siren } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FieldValues } from "react-hook-form";
|
import { FieldValues } from "react-hook-form";
|
||||||
|
|
||||||
type MissionStationsSelectProps<T extends FieldValues> = {
|
type MissionStationsSelectProps = {
|
||||||
selectedStations?: number[];
|
selectedStations?: number[];
|
||||||
className?: string;
|
className?: string;
|
||||||
menuPlacement?: "top" | "bottom" | "auto"; // Added menuPlacement prop for better control
|
menuPlacement?: "top" | "bottom" | "auto"; // Added menuPlacement prop for better control
|
||||||
@@ -27,7 +27,7 @@ type MissionStationsSelectProps<T extends FieldValues> = {
|
|||||||
isMulti?: boolean;
|
isMulti?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function StationsSelect<T extends FieldValues>({
|
export function StationsSelect({
|
||||||
onChange,
|
onChange,
|
||||||
selectedStations,
|
selectedStations,
|
||||||
vehicleStates,
|
vehicleStates,
|
||||||
@@ -35,7 +35,7 @@ export function StationsSelect<T extends FieldValues>({
|
|||||||
isMulti = true,
|
isMulti = true,
|
||||||
menuPlacement = "bottom",
|
menuPlacement = "bottom",
|
||||||
filterSelected = false,
|
filterSelected = false,
|
||||||
}: MissionStationsSelectProps<T>) {
|
}: MissionStationsSelectProps) {
|
||||||
const { data: connectedAircrafts } = useQuery({
|
const { data: connectedAircrafts } = useQuery({
|
||||||
queryKey: ["aircrafts"],
|
queryKey: ["aircrafts"],
|
||||||
queryFn: () => getConnectedAircraftsAPI(),
|
queryFn: () => getConnectedAircraftsAPI(),
|
||||||
@@ -47,11 +47,21 @@ export function StationsSelect<T extends FieldValues>({
|
|||||||
|
|
||||||
const [value, setValue] = useState<string[]>(selectedStations?.map((id) => String(id)) || []);
|
const [value, setValue] = useState<string[]>(selectedStations?.map((id) => String(id)) || []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setValue([
|
||||||
|
...(selectedStations || []).map((id) => String(id)),
|
||||||
|
...(vehicleStates.hpgAmbulanceState !== HpgState.NOT_REQUESTED ? ["RTW"] : []),
|
||||||
|
...(vehicleStates.hpgFireEngineState !== HpgState.NOT_REQUESTED ? ["FW"] : []),
|
||||||
|
...(vehicleStates.hpgPoliceState !== HpgState.NOT_REQUESTED ? ["POL"] : []),
|
||||||
|
]);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [selectedStations, vehicleStates]);
|
||||||
|
|
||||||
// Helper to check if a station is a vehicle and its state is NOT_REQUESTED
|
// Helper to check if a station is a vehicle and its state is NOT_REQUESTED
|
||||||
const stationsOptions = [
|
const stationsOptions = [
|
||||||
...(stations?.map((station) => ({
|
...(stations?.map((station) => ({
|
||||||
label: station.bosCallsign,
|
label: station.bosCallsign,
|
||||||
value: station.id,
|
value: String(station.id),
|
||||||
type: "station" as const,
|
type: "station" as const,
|
||||||
isOnline: !!connectedAircrafts?.find((a) => a.stationId === station.id),
|
isOnline: !!connectedAircrafts?.find((a) => a.stationId === station.id),
|
||||||
})) || []),
|
})) || []),
|
||||||
@@ -78,7 +88,7 @@ export function StationsSelect<T extends FieldValues>({
|
|||||||
if (!filterSelected) return true; // If filterSelected is false, include all stations
|
if (!filterSelected) return true; // If filterSelected is false, include all stations
|
||||||
// Filter out selected stations if filterSelectedStations is true
|
// Filter out selected stations if filterSelectedStations is true
|
||||||
if (s.type === "station") {
|
if (s.type === "station") {
|
||||||
return !selectedStations?.includes(s.value);
|
return !selectedStations?.map(String)?.includes(s.value);
|
||||||
}
|
}
|
||||||
// If the station is a vehicle, we need to check its state
|
// If the station is a vehicle, we need to check its state
|
||||||
if (s.type === "vehicle") {
|
if (s.type === "vehicle") {
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import {
|
|||||||
startHpgValidation,
|
startHpgValidation,
|
||||||
} from "_querys/missions";
|
} from "_querys/missions";
|
||||||
import { getKeywordsAPI } from "_querys/keywords";
|
import { getKeywordsAPI } from "_querys/keywords";
|
||||||
import { getStationsAPI } from "_querys/stations";
|
|
||||||
import { useMapStore } from "_store/mapStore";
|
import { useMapStore } from "_store/mapStore";
|
||||||
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
|
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
|
||||||
import { HPGValidationRequired } from "_helpers/hpgValidationRequired";
|
import { HPGValidationRequired } from "_helpers/hpgValidationRequired";
|
||||||
@@ -197,7 +196,7 @@ export const MissionForm = () => {
|
|||||||
}
|
}
|
||||||
return newMission;
|
return newMission;
|
||||||
};
|
};
|
||||||
console.log(form.formState.errors);
|
console.log(form.watch("missionStationIds"));
|
||||||
return (
|
return (
|
||||||
<form className="space-y-4">
|
<form className="space-y-4">
|
||||||
{/* Koorinaten Section */}
|
{/* Koorinaten Section */}
|
||||||
@@ -282,12 +281,12 @@ export const MissionForm = () => {
|
|||||||
className="select select-primary select-bordered w-full mb-4"
|
className="select select-primary select-bordered w-full mb-4"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
form.setValue("type", e.target.value as missionType);
|
form.setValue("type", e.target.value as missionType);
|
||||||
if (e.target.value === "sekundär") {
|
if (e.target.value === "primary") {
|
||||||
form.setValue("missionKeywordName", KEYWORD_CATEGORY.Z_SONSTIGES);
|
form.setValue("missionKeywordName", null as any);
|
||||||
form.setValue("missionKeywordAbbreviation", "VL_S");
|
form.setValue("missionKeywordAbbreviation", null as any);
|
||||||
form.setValue("hpgMissionString", "Verlegung:4_1_1_1-4_1");
|
form.setValue("hpgMissionString", null);
|
||||||
} else {
|
} else {
|
||||||
form.setValue("missionKeywordCategory", "V_VERLEGUNG");
|
form.setValue("missionKeywordCategory", KEYWORD_CATEGORY.V_VERLEGUNG);
|
||||||
form.setValue("missionKeywordAbbreviation", null as any);
|
form.setValue("missionKeywordAbbreviation", null as any);
|
||||||
form.setValue("hpgMissionString", null);
|
form.setValue("hpgMissionString", null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,15 +16,15 @@ const Map = dynamic(() => import("_components/map/Map"), {
|
|||||||
ssr: false,
|
ssr: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const DispatchPage = () => {
|
const PilotPage = () => {
|
||||||
const { connectedAircraft, status } = usePilotConnectionStore((state) => state);
|
const { connectedAircraft, status } = usePilotConnectionStore((state) => state);
|
||||||
const { data: ownAircraftArray = [] } = useQuery({
|
const { data: ownAircraftArray = [] } = useQuery({
|
||||||
queryKey: ["aircrafts", connectedAircraft?.id],
|
queryKey: ["own-aircraft", connectedAircraft?.id],
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
getAircraftsAPI({
|
getAircraftsAPI({
|
||||||
id: connectedAircraft?.id,
|
id: connectedAircraft?.id,
|
||||||
}),
|
}),
|
||||||
refetchInterval: 1000,
|
refetchInterval: 10000,
|
||||||
});
|
});
|
||||||
const ownAircraft = ownAircraftArray[0];
|
const ownAircraft = ownAircraftArray[0];
|
||||||
const simulatorConnected = ownAircraft ? checkSimulatorConnected(ownAircraft) : false;
|
const simulatorConnected = ownAircraft ? checkSimulatorConnected(ownAircraft) : false;
|
||||||
@@ -73,6 +73,6 @@ const DispatchPage = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
DispatchPage.displayName = "DispatchPage";
|
PilotPage.displayName = "DispatchPage";
|
||||||
|
|
||||||
export default DispatchPage;
|
export default PilotPage;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ export function QueryProvider({ children }: { children: ReactNode }) {
|
|||||||
const handleNotification = (notification: NotificationPayload) => {
|
const handleNotification = (notification: NotificationPayload) => {
|
||||||
switch (notification.type) {
|
switch (notification.type) {
|
||||||
case "hpg-validation":
|
case "hpg-validation":
|
||||||
|
console.log("hpg-validation notification received", notification);
|
||||||
toast.custom(
|
toast.custom(
|
||||||
(t) => <HPGnotificationToast event={notification} mapStore={mapStore} t={t} />,
|
(t) => <HPGnotificationToast event={notification} mapStore={mapStore} t={t} />,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ const AircraftPopupContent = ({
|
|||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
className="flex gap-[2px] text-white pb-0.5"
|
className="flex gap-[2px] text-white pb-0.5 overflow-auto"
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: `${FMS_STATUS_TEXT_COLORS[aircraft.fmsStatus]}`,
|
backgroundColor: `${FMS_STATUS_TEXT_COLORS[aircraft.fmsStatus]}`,
|
||||||
}}
|
}}
|
||||||
@@ -152,21 +152,26 @@ const AircraftPopupContent = ({
|
|||||||
{aircraft.fmsStatus}
|
{aircraft.fmsStatus}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="w-100 cursor-pointer px-2"
|
className="cursor-pointer px-2 min-w-[130px]"
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: `${FMS_STATUS_COLORS[aircraft.fmsStatus]}`,
|
backgroundColor: `${FMS_STATUS_COLORS[aircraft.fmsStatus]}`,
|
||||||
borderBottom:
|
borderBottom:
|
||||||
currentTab === "aircraft"
|
currentTab === "aircraft"
|
||||||
? `5px solid ${FMS_STATUS_TEXT_COLORS[aircraft.fmsStatus]}`
|
? `5px solid ${FMS_STATUS_TEXT_COLORS[aircraft.fmsStatus]}`
|
||||||
: "5px solid transparent",
|
: "5px solid transparent",
|
||||||
whiteSpace: "nowrap",
|
|
||||||
}}
|
}}
|
||||||
onClick={() => handleTabChange("aircraft")}
|
onClick={() => handleTabChange("aircraft")}
|
||||||
>
|
>
|
||||||
<span className="text-white text-base font-medium">
|
<span className="text-white text-base font-medium truncate">
|
||||||
{aircraft.Station.bosCallsign}
|
{aircraft.Station.bosCallsign.length > 20
|
||||||
|
? aircraft.Station.bosCallsignShort
|
||||||
|
: aircraft.Station.bosCallsign}
|
||||||
|
</span>
|
||||||
|
<span className="text-sm text-gray-400">
|
||||||
<br />
|
<br />
|
||||||
{aircraft.Station.bosUse}
|
{aircraft.Station.bosUse === "DUAL_USE" && "(dual use)"}
|
||||||
|
{aircraft.Station.bosUse === "PRIMARY" && "(primär)"}
|
||||||
|
{aircraft.Station.bosUse === "SECONDARY" && "(sekundär)"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -184,7 +189,7 @@ const AircraftPopupContent = ({
|
|||||||
<span className="text-white text-base font-medium">Einsatz</span>
|
<span className="text-white text-base font-medium">Einsatz</span>
|
||||||
<br />
|
<br />
|
||||||
<span className="text-white text-sm font-medium">
|
<span className="text-white text-sm font-medium">
|
||||||
{mission?.publicId || "Kein aktiver Einsatz"}
|
{mission?.publicId || "kein Einsatz"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ const StationsLayer = ({ attribution }: { attribution: Control.Attribution }) =>
|
|||||||
queryKey: ["stations"],
|
queryKey: ["stations"],
|
||||||
queryFn: () => getStationsAPI(),
|
queryFn: () => getStationsAPI(),
|
||||||
});
|
});
|
||||||
console.log("StationsLayer: stations", stations);
|
|
||||||
|
|
||||||
const [selectedStations, setSelectedStations] = useState<Station["id"][]>([]);
|
const [selectedStations, setSelectedStations] = useState<Station["id"][]>([]);
|
||||||
const attributionText = "";
|
const attributionText = "";
|
||||||
@@ -306,14 +305,6 @@ const WindfarmOutlineLayer = () => {
|
|||||||
|
|
||||||
export const BaseMaps = () => {
|
export const BaseMaps = () => {
|
||||||
const map = useMap();
|
const map = useMap();
|
||||||
const isPannelOpen = usePannelStore((state) => state.isOpen);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
map.invalidateSize();
|
|
||||||
}, 600);
|
|
||||||
}, [isPannelOpen]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LayersControl position="topleft">
|
<LayersControl position="topleft">
|
||||||
<LayersControl.Overlay name={"Leitstellenbereiche"}>
|
<LayersControl.Overlay name={"Leitstellenbereiche"}>
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ import { Prisma, prisma } from "@repo/db";
|
|||||||
|
|
||||||
export async function GET(request: NextRequest): Promise<NextResponse> {
|
export async function GET(request: NextRequest): Promise<NextResponse> {
|
||||||
try {
|
try {
|
||||||
|
const config = await prisma.config.findFirst({
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
const filter = JSON.parse(
|
const filter = JSON.parse(
|
||||||
new URL(request.url).searchParams.get("filter") || "{}",
|
new URL(request.url).searchParams.get("filter") || "{}",
|
||||||
) as Prisma.ConnectedAircraftWhereInput;
|
) as Prisma.ConnectedAircraftWhereInput;
|
||||||
@@ -16,9 +21,15 @@ export async function GET(request: NextRequest): Promise<NextResponse> {
|
|||||||
Station: true,
|
Station: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return NextResponse.json(connectedAircraft, {
|
return NextResponse.json(
|
||||||
status: 200,
|
connectedAircraft.map((a) => ({
|
||||||
});
|
...a,
|
||||||
|
posH145active: config?.disableHPG ? false : a.posH145active,
|
||||||
|
})),
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
},
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return NextResponse.json({ error: "Failed to fetch Aircrafts" }, { status: 500 });
|
return NextResponse.json({ error: "Failed to fetch Aircrafts" }, { status: 500 });
|
||||||
|
|||||||
Reference in New Issue
Block a user