Added Aircraft log to mission
This commit is contained in:
@@ -1,4 +1,10 @@
|
|||||||
import { prisma } from "@repo/db";
|
import {
|
||||||
|
ConnectedAircraft,
|
||||||
|
getPublicUser,
|
||||||
|
MissionLog,
|
||||||
|
Prisma,
|
||||||
|
prisma,
|
||||||
|
} from "@repo/db";
|
||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import { io } from "../index";
|
import { io } from "../index";
|
||||||
|
|
||||||
@@ -39,11 +45,58 @@ router.get("/:id", async (req, res) => {
|
|||||||
// Update a connectedAircraft by ID
|
// Update a connectedAircraft by ID
|
||||||
router.patch("/:id", async (req, res) => {
|
router.patch("/:id", async (req, res) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
const aircraftUpdate = req.body as Prisma.ConnectedAircraftUpdateInput;
|
||||||
try {
|
try {
|
||||||
|
const oldConnectedAircraft = await prisma.connectedAircraft.findUnique({
|
||||||
|
where: { id: Number(id) },
|
||||||
|
include: {
|
||||||
|
Station: true,
|
||||||
|
User: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
const updatedConnectedAircraft = await prisma.connectedAircraft.update({
|
const updatedConnectedAircraft = await prisma.connectedAircraft.update({
|
||||||
where: { id: Number(id) },
|
where: { id: Number(id) },
|
||||||
data: req.body,
|
data: {
|
||||||
|
...aircraftUpdate,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const mission = await prisma.mission.findFirst({
|
||||||
|
where: {
|
||||||
|
state: "running",
|
||||||
|
missionStationIds: {
|
||||||
|
has: updatedConnectedAircraft.stationId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (
|
||||||
|
mission &&
|
||||||
|
aircraftUpdate.fmsStatus &&
|
||||||
|
oldConnectedAircraft &&
|
||||||
|
updatedConnectedAircraft &&
|
||||||
|
oldConnectedAircraft.fmsStatus !== updatedConnectedAircraft.fmsStatus
|
||||||
|
) {
|
||||||
|
const newMissionLog = mission.missionLog as any as MissionLog[];
|
||||||
|
newMissionLog.push({
|
||||||
|
type: "station-log",
|
||||||
|
auto: true,
|
||||||
|
data: {
|
||||||
|
oldFMSstatus: oldConnectedAircraft.fmsStatus,
|
||||||
|
newFMSstatus: updatedConnectedAircraft.fmsStatus,
|
||||||
|
station: oldConnectedAircraft.Station,
|
||||||
|
stationId: updatedConnectedAircraft.stationId,
|
||||||
|
user: getPublicUser(oldConnectedAircraft.User),
|
||||||
|
},
|
||||||
|
timeStamp: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
await prisma.mission.update({
|
||||||
|
where: { id: mission.id },
|
||||||
|
data: {
|
||||||
|
missionLog: newMissionLog as any,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
io.to("dispatchers").emit(
|
io.to("dispatchers").emit(
|
||||||
"update-connectedAircraft",
|
"update-connectedAircraft",
|
||||||
updatedConnectedAircraft,
|
updatedConnectedAircraft,
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import { User } from "@repo/db";
|
import { User } from "@repo/db";
|
||||||
import { Socket, Server } from "socket.io";
|
import { Socket, Server } from "socket.io";
|
||||||
|
|
||||||
export const handleConnectDesktop =
|
export const handleConnectDesktop = (socket: Socket, io: Server) => () => {
|
||||||
(socket: Socket, io: Server) => (socket: Socket) => {
|
|
||||||
const user = socket.data.user as User;
|
const user = socket.data.user as User;
|
||||||
console.log("connect-desktop", user.publicId);
|
console.log("connect-desktop", user.publicId);
|
||||||
socket.join(`user:${user.id}`);
|
socket.join(`user:${user.id}`);
|
||||||
socket.join(`desktop:${user.id}`);
|
socket.join(`desktop:${user.id}`);
|
||||||
|
|
||||||
socket.on("ptt", (data) => {
|
socket.on("ptt", (data) => {
|
||||||
console.log("ptt", data);
|
|
||||||
socket.to(`user:${user.id}`).emit("ptt", data);
|
socket.to(`user:${user.id}`).emit("ptt", data);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ export function QueryProvider({ children }: { children: ReactNode }) {
|
|||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: ["aircrafts"],
|
queryKey: ["aircrafts"],
|
||||||
});
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ["missions"],
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
dispatchSocket.on("update-mission", invalidateMission);
|
dispatchSocket.on("update-mission", invalidateMission);
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ interface PTTData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handlePTT = (data: PTTData) => {
|
const handlePTT = (data: PTTData) => {
|
||||||
|
console.log("PTT", data);
|
||||||
const { shouldTransmit, source } = data;
|
const { shouldTransmit, source } = data;
|
||||||
const { room } = useAudioStore.getState();
|
const { room } = useAudioStore.getState();
|
||||||
if (!room) return;
|
if (!room) return;
|
||||||
|
|||||||
@@ -6,11 +6,14 @@ export async function GET(req: NextRequest): Promise<NextResponse> {
|
|||||||
const id = searchParams.get("id");
|
const id = searchParams.get("id");
|
||||||
const filter = searchParams.get("filter");
|
const filter = searchParams.get("filter");
|
||||||
|
|
||||||
|
console.log(filter);
|
||||||
|
const filterParsed = JSON.parse(filter || "{}");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await prisma.mission.findMany({
|
const data = await prisma.mission.findMany({
|
||||||
where: {
|
where: {
|
||||||
id: id ? Number(id) : undefined,
|
id: id ? Number(id) : undefined,
|
||||||
...(filter ? JSON.parse(filter) : {}),
|
...filterParsed,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import FMSStatusHistory, {
|
|||||||
FMSStatusSelector,
|
FMSStatusSelector,
|
||||||
MissionTab,
|
MissionTab,
|
||||||
RettungsmittelTab,
|
RettungsmittelTab,
|
||||||
|
SDSTab,
|
||||||
} from "./_components/AircraftMarkerTabs";
|
} from "./_components/AircraftMarkerTabs";
|
||||||
import { ConnectedAircraft, Station } from "@repo/db";
|
import { ConnectedAircraft, Station } from "@repo/db";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
@@ -100,22 +101,24 @@ const AircraftPopupContent = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { data: missions } = useQuery({
|
const { data: missions } = useQuery({
|
||||||
queryKey: ["missions"],
|
queryKey: ["missions", "missions-map"],
|
||||||
queryFn: () => getMissionsAPI(),
|
queryFn: () =>
|
||||||
|
getMissionsAPI({
|
||||||
|
state: "running",
|
||||||
|
missionStationIds: {
|
||||||
|
has: aircraft.Station.id,
|
||||||
|
},
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mission = useMemo(() => {
|
console.log("Missions", missions);
|
||||||
return missions?.find(
|
|
||||||
(m) =>
|
const mission = missions && missions[0];
|
||||||
(m.state === "running" || m.state === "draft") &&
|
|
||||||
m.missionStationIds.includes(aircraft.Station.id),
|
|
||||||
);
|
|
||||||
}, [missions, aircraft.Station.id]);
|
|
||||||
|
|
||||||
const renderTabContent = useMemo(() => {
|
const renderTabContent = useMemo(() => {
|
||||||
switch (currentTab) {
|
switch (currentTab) {
|
||||||
case "home":
|
case "home":
|
||||||
return <FMSStatusHistory aircraft={aircraft} />;
|
return <FMSStatusHistory aircraft={aircraft} mission={mission} />;
|
||||||
case "fms":
|
case "fms":
|
||||||
return <FMSStatusSelector aircraft={aircraft} />;
|
return <FMSStatusSelector aircraft={aircraft} />;
|
||||||
case "aircraft":
|
case "aircraft":
|
||||||
@@ -127,7 +130,7 @@ const AircraftPopupContent = ({
|
|||||||
<span className="text-gray-100">No mission available</span>
|
<span className="text-gray-100">No mission available</span>
|
||||||
);
|
);
|
||||||
case "chat":
|
case "chat":
|
||||||
return <div>Chat Content</div>;
|
return <SDSTab aircraft={aircraft} mission={mission} />;
|
||||||
default:
|
default:
|
||||||
return <span className="text-gray-100">Error</span>;
|
return <span className="text-gray-100">Error</span>;
|
||||||
}
|
}
|
||||||
@@ -395,7 +398,7 @@ const AircraftMarker = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment key={aircraft.id}>
|
<Fragment key={aircraft.id}>
|
||||||
{checkSimulatorConnected(aircraft.lastHeartbeat) && (
|
{
|
||||||
<Marker
|
<Marker
|
||||||
ref={markerRef}
|
ref={markerRef}
|
||||||
position={[aircraft.posLat!, aircraft.posLng!]}
|
position={[aircraft.posLat!, aircraft.posLng!]}
|
||||||
@@ -406,7 +409,7 @@ const AircraftMarker = ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
}
|
||||||
{openAircraftMarker.some((m) => m.id === aircraft.id) && !hideMarker && (
|
{openAircraftMarker.some((m) => m.id === aircraft.id) && !hideMarker && (
|
||||||
<SmartPopup
|
<SmartPopup
|
||||||
options={{
|
options={{
|
||||||
@@ -439,7 +442,9 @@ export const AircraftLayer = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{aircrafts?.map((aircraft) => {
|
{aircrafts
|
||||||
|
?.filter((a) => checkSimulatorConnected(a.lastHeartbeat))
|
||||||
|
?.map((aircraft) => {
|
||||||
return <AircraftMarker key={aircraft.id} aircraft={aircraft} />;
|
return <AircraftMarker key={aircraft.id} aircraft={aircraft} />;
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { FMS_STATUS_COLORS, FMS_STATUS_TEXT_COLORS } from "../AircraftMarker";
|
import { FMS_STATUS_COLORS, FMS_STATUS_TEXT_COLORS } from "../AircraftMarker";
|
||||||
import { ConnectedAircraft, Mission, Prisma, Station } from "@repo/db";
|
import {
|
||||||
|
ConnectedAircraft,
|
||||||
|
getPublicUser,
|
||||||
|
Mission,
|
||||||
|
MissionLog,
|
||||||
|
MissionSdsLog,
|
||||||
|
MissionStationLog,
|
||||||
|
Prisma,
|
||||||
|
Station,
|
||||||
|
} from "@repo/db";
|
||||||
import { toast } from "react-hot-toast";
|
import { toast } from "react-hot-toast";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { editConnectedAircraftAPI } from "querys/aircrafts";
|
import { editConnectedAircraftAPI } from "querys/aircrafts";
|
||||||
@@ -9,6 +18,7 @@ import { useDispatchConnectionStore } from "_store/dispatch/connectionStore";
|
|||||||
import { cn } from "helpers/cn";
|
import { cn } from "helpers/cn";
|
||||||
import { PersonIcon } from "@radix-ui/react-icons";
|
import { PersonIcon } from "@radix-ui/react-icons";
|
||||||
import {
|
import {
|
||||||
|
Ban,
|
||||||
BellRing,
|
BellRing,
|
||||||
CircleGaugeIcon,
|
CircleGaugeIcon,
|
||||||
Clock,
|
Clock,
|
||||||
@@ -21,31 +31,30 @@ import {
|
|||||||
MapPin,
|
MapPin,
|
||||||
Mountain,
|
Mountain,
|
||||||
Navigation,
|
Navigation,
|
||||||
|
Plus,
|
||||||
RadioTower,
|
RadioTower,
|
||||||
Sunset,
|
Sunset,
|
||||||
TextSearch,
|
TextSearch,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
import { useSession } from "next-auth/react";
|
||||||
|
import { editMissionAPI } from "querys/missions";
|
||||||
|
|
||||||
const FMSStatusHistory = ({
|
const FMSStatusHistory = ({
|
||||||
aircraft,
|
aircraft,
|
||||||
|
mission,
|
||||||
}: {
|
}: {
|
||||||
aircraft: ConnectedAircraft & { Station: Station };
|
aircraft: ConnectedAircraft & { Station: Station };
|
||||||
|
mission?: Mission;
|
||||||
}) => {
|
}) => {
|
||||||
const dummyData = [
|
console.log("FMSStatusHistory", mission?.missionLog);
|
||||||
{ status: "3", time: "12:00" },
|
const log = ((mission?.missionLog as unknown as MissionLog[]) || [])
|
||||||
{ status: "4", time: "12:30" },
|
.filter(
|
||||||
{ status: "7", time: "14:54" },
|
(entry) =>
|
||||||
{ status: "8", time: "15:30" },
|
entry.type === "station-log" &&
|
||||||
{ status: "1", time: "16:30" },
|
entry.data.stationId === aircraft.Station.id,
|
||||||
{ status: "4", time: "17:30" },
|
)
|
||||||
{ status: "7", time: "18:54" },
|
.reverse()
|
||||||
{ status: "8", time: "19:30" },
|
.splice(0, 6) as MissionStationLog[];
|
||||||
{ status: "1", time: "20:30" },
|
|
||||||
{ status: "4", time: "21:30" },
|
|
||||||
{ status: "7", time: "22:54" },
|
|
||||||
{ status: "8", time: "23:30" },
|
|
||||||
{ status: "1", time: "24:30" },
|
|
||||||
];
|
|
||||||
|
|
||||||
const aircraftUser =
|
const aircraftUser =
|
||||||
typeof aircraft.publicUser === "string"
|
typeof aircraft.publicUser === "string"
|
||||||
@@ -62,20 +71,22 @@ const FMSStatusHistory = ({
|
|||||||
</ul>
|
</ul>
|
||||||
<div className="divider mt-0 mb-0" />
|
<div className="divider mt-0 mb-0" />
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-2">
|
||||||
{dummyData
|
{log.map((entry, index) => (
|
||||||
.reverse()
|
|
||||||
.slice(0, 6)
|
|
||||||
.map((entry, index) => (
|
|
||||||
<li key={index} className="flex items-center gap-2">
|
<li key={index} className="flex items-center gap-2">
|
||||||
<span
|
<span
|
||||||
className="font-bold text-base"
|
className="font-bold text-base"
|
||||||
style={{
|
style={{
|
||||||
color: FMS_STATUS_TEXT_COLORS[entry.status],
|
color: FMS_STATUS_TEXT_COLORS[entry.data.newFMSstatus],
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{entry.status}
|
{entry.data.newFMSstatus}
|
||||||
|
</span>
|
||||||
|
<span className="text-base-content">
|
||||||
|
{new Date(entry.timeStamp).toLocaleTimeString([], {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
})}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-base-content">{entry.time}</span>
|
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -272,5 +283,143 @@ const MissionTab = ({ mission }: { mission: Mission }) => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export { FMSStatusSelector, RettungsmittelTab, MissionTab };
|
|
||||||
|
const SDSTab = ({
|
||||||
|
aircraft,
|
||||||
|
mission,
|
||||||
|
}: {
|
||||||
|
aircraft: ConnectedAircraft & {
|
||||||
|
Station: Station;
|
||||||
|
};
|
||||||
|
mission?: Mission;
|
||||||
|
}) => {
|
||||||
|
const session = useSession();
|
||||||
|
const [isChatOpen, setIsChatOpen] = useState(false);
|
||||||
|
const [note, setNote] = useState("");
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const editMissionMutation = useMutation({
|
||||||
|
mutationFn: ({
|
||||||
|
id,
|
||||||
|
mission,
|
||||||
|
}: {
|
||||||
|
id: number;
|
||||||
|
mission: Partial<Prisma.MissionUpdateInput>;
|
||||||
|
}) => editMissionAPI(id, mission),
|
||||||
|
mutationKey: ["missions"],
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["missions"] });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const log = (mission?.missionLog as unknown as MissionLog[])
|
||||||
|
.slice()
|
||||||
|
.reverse()
|
||||||
|
.filter(
|
||||||
|
(entry) =>
|
||||||
|
entry.type === "sds-log" &&
|
||||||
|
entry.data.stationId === aircraft.Station.id,
|
||||||
|
);
|
||||||
|
console.log(mission?.missionLog, log);
|
||||||
|
return (
|
||||||
|
<div className="p-4">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{!isChatOpen ? (
|
||||||
|
<button
|
||||||
|
className="text-base-content text-base cursor-pointer"
|
||||||
|
onClick={() => setIsChatOpen(true)}
|
||||||
|
>
|
||||||
|
<span className="flex items-center gap-2">
|
||||||
|
<Plus size={18} /> Notiz hinzufügen
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center gap-2 w-full">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder=""
|
||||||
|
className="input input-sm text-base-content flex-1"
|
||||||
|
value={note}
|
||||||
|
onChange={(e) => setNote(e.target.value)}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-primary btn-outline"
|
||||||
|
onClick={() => {
|
||||||
|
if (!mission) return;
|
||||||
|
const newMissionLog = [
|
||||||
|
...mission.missionLog,
|
||||||
|
{
|
||||||
|
type: "sds-log",
|
||||||
|
auto: false,
|
||||||
|
timeStamp: new Date().toISOString(),
|
||||||
|
data: {
|
||||||
|
stationId: aircraft.Station.id,
|
||||||
|
station: aircraft.Station,
|
||||||
|
message: note,
|
||||||
|
user: getPublicUser(session.data!.user),
|
||||||
|
},
|
||||||
|
} as MissionSdsLog,
|
||||||
|
];
|
||||||
|
editMissionMutation
|
||||||
|
.mutateAsync({
|
||||||
|
id: mission.id,
|
||||||
|
mission: {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
missionLog: newMissionLog as any,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
setIsChatOpen(false);
|
||||||
|
setNote("");
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Plus size={20} />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-outline"
|
||||||
|
onClick={() => {
|
||||||
|
setIsChatOpen(false);
|
||||||
|
setNote("");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ban size={20} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="divider m-0" />
|
||||||
|
<ul className="space-y-2 max-h-[300px] overflow-y-auto overflow-x-auto">
|
||||||
|
{log.map((entry, index) => {
|
||||||
|
const sdsEntry = entry as MissionSdsLog;
|
||||||
|
return (
|
||||||
|
<li key={index} className="flex items-center gap-2">
|
||||||
|
<span className="text-base-content">
|
||||||
|
{new Date(sdsEntry.timeStamp).toLocaleTimeString([], {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="font-bold text-base"
|
||||||
|
style={{
|
||||||
|
color: FMS_STATUS_TEXT_COLORS[6],
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{sdsEntry.data.user.firstname?.[0]?.toUpperCase() ?? "?"}
|
||||||
|
{sdsEntry.data.user.lastname?.[0]?.toUpperCase() ?? "?"}
|
||||||
|
</span>
|
||||||
|
<span className="text-base-content">{sdsEntry.data.message}</span>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{!log.length && (
|
||||||
|
<p className="text-gray-500">Kein SDS-Verlauf verfügbar</p>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { FMSStatusSelector, RettungsmittelTab, MissionTab, SDSTab };
|
||||||
export default FMSStatusHistory;
|
export default FMSStatusHistory;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import {
|
|||||||
User,
|
User,
|
||||||
SmartphoneNfc,
|
SmartphoneNfc,
|
||||||
CheckCheck,
|
CheckCheck,
|
||||||
|
ArrowRight,
|
||||||
|
Cross,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import {
|
import {
|
||||||
getPublicUser,
|
getPublicUser,
|
||||||
@@ -212,6 +214,13 @@ const Patientdetails = ({ mission }: { mission: Mission }) => {
|
|||||||
<p className="text-base-content font-semibold">
|
<p className="text-base-content font-semibold">
|
||||||
{mission.missionPatientInfo}
|
{mission.missionPatientInfo}
|
||||||
</p>
|
</p>
|
||||||
|
<div className="divider my-2" />
|
||||||
|
<h2 className="flex items-center gap-2 text-lg font-bold mb-3">
|
||||||
|
<Cross /> Einsatzinformationen
|
||||||
|
</h2>
|
||||||
|
<p className="text-base-content font-semibold">
|
||||||
|
{mission.missionAdditionalInfo}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -333,6 +342,7 @@ const FMSStatusHistory = ({ mission }: { mission: Mission }) => {
|
|||||||
queryClient.invalidateQueries({ queryKey: ["missions"] });
|
queryClient.invalidateQueries({ queryKey: ["missions"] });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
console.log(mission.missionLog);
|
||||||
|
|
||||||
if (!session.data?.user) return null;
|
if (!session.data?.user) return null;
|
||||||
return (
|
return (
|
||||||
@@ -400,7 +410,7 @@ const FMSStatusHistory = ({ mission }: { mission: Mission }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="divider m-0" />
|
<div className="divider m-0" />
|
||||||
<ul className="space-y-2 max-h-[300px] overflow-y-auto overflow-x-auto">
|
<ul className="space-y-1 max-h-[300px] overflow-y-auto overflow-x-auto">
|
||||||
{(mission.missionLog as unknown as MissionLog[])
|
{(mission.missionLog as unknown as MissionLog[])
|
||||||
.slice()
|
.slice()
|
||||||
.reverse()
|
.reverse()
|
||||||
@@ -408,7 +418,12 @@ const FMSStatusHistory = ({ mission }: { mission: Mission }) => {
|
|||||||
if (entry.type === "station-log")
|
if (entry.type === "station-log")
|
||||||
return (
|
return (
|
||||||
<li key={index} className="flex items-center gap-2">
|
<li key={index} className="flex items-center gap-2">
|
||||||
<span className="text-base-content">{entry.timeStamp}</span>
|
<span className="text-base-content">
|
||||||
|
{new Date(entry.timeStamp).toLocaleTimeString([], {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
<span
|
<span
|
||||||
className="font-bold text-base"
|
className="font-bold text-base"
|
||||||
style={{
|
style={{
|
||||||
@@ -422,7 +437,7 @@ const FMSStatusHistory = ({ mission }: { mission: Mission }) => {
|
|||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
if (entry.type === "message-log")
|
if (entry.type === "message-log" || entry.type === "sds-log")
|
||||||
return (
|
return (
|
||||||
<li key={index} className="flex items-center gap-2">
|
<li key={index} className="flex items-center gap-2">
|
||||||
<span className="text-base-content">
|
<span className="text-base-content">
|
||||||
@@ -432,13 +447,33 @@ const FMSStatusHistory = ({ mission }: { mission: Mission }) => {
|
|||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className="font-bold text-base"
|
className="font-bold text-base flex items-center gap-0.5"
|
||||||
style={{
|
style={{
|
||||||
color: FMS_STATUS_TEXT_COLORS[6],
|
color: FMS_STATUS_TEXT_COLORS[6],
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{entry.data.user.firstname?.[0]?.toUpperCase() ?? "?"}
|
{entry.data.user.firstname?.[0]?.toUpperCase() ?? "?"}
|
||||||
{entry.data.user.lastname?.[0]?.toUpperCase() ?? "?"}
|
{entry.data.user.lastname?.[0]?.toUpperCase() ?? "?"}
|
||||||
|
{entry.type === "sds-log" && (
|
||||||
|
<>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
className="size-4"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
{entry.data.station.bosCallsignShort}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-base-content">
|
<span className="text-base-content">
|
||||||
{entry.data.message}
|
{entry.data.message}
|
||||||
|
|||||||
@@ -13,27 +13,36 @@ export const ConnectionBtn = () => {
|
|||||||
const session = useSession();
|
const session = useSession();
|
||||||
const uid = session.data?.user?.id;
|
const uid = session.data?.user?.id;
|
||||||
if (!uid) return null;
|
if (!uid) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rounded-box bg-base-200 flex justify-center items-center gap-2 p-1">
|
<div className="rounded-box bg-base-200 flex justify-center items-center gap-2 p-1">
|
||||||
{connection.message.length > 0 && (
|
{connection.message.length > 0 && (
|
||||||
<span className="mx-2 text-error">{connection.message}</span>
|
<span className="mx-2 text-error">{connection.message}</span>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{connection.status === "disconnected" && (
|
{connection.status == "connected" ? (
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-soft btn-info "
|
className="btn btn-soft btn-error"
|
||||||
onClick={() => modalRef.current?.showModal()}
|
type="submit"
|
||||||
|
onSubmit={() => false}
|
||||||
|
onClick={() => {
|
||||||
|
connection.disconnect();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Verbinden
|
Trennen
|
||||||
</button>
|
</button>
|
||||||
)}
|
) : (
|
||||||
|
|
||||||
{connection.status == "connected" && (
|
|
||||||
<button
|
<button
|
||||||
className="btn btn-soft btn-success"
|
type="submit"
|
||||||
onClick={() => modalRef.current?.showModal()}
|
onSubmit={() => false}
|
||||||
|
onClick={() => {
|
||||||
|
modalRef.current?.showModal();
|
||||||
|
}}
|
||||||
|
className="btn btn-soft btn-info"
|
||||||
>
|
>
|
||||||
Verbunden
|
{connection.status == "disconnected"
|
||||||
|
? "Verbinden"
|
||||||
|
: connection.status}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -93,7 +102,9 @@ export const ConnectionBtn = () => {
|
|||||||
}}
|
}}
|
||||||
className="btn btn-soft btn-info"
|
className="btn btn-soft btn-info"
|
||||||
>
|
>
|
||||||
{connection.status == "disconnected"
|
{connection.status == "disconnected" ||
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(connection.status as any) === ""
|
||||||
? "Verbinden"
|
? "Verbinden"
|
||||||
: connection.status}
|
: connection.status}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
export const checkSimulatorConnected = (date: Date) =>
|
export const checkSimulatorConnected = (date: Date) =>
|
||||||
date && Date.now() - new Date(date).getTime() <= 30_000;
|
date && Date.now() - new Date(date).getTime() <= 3000_000;
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export const ConnectionBtn = () => {
|
|||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Verbindung Trennen
|
Trennen
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
|
|||||||
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
import { Station, User } from "../../generated/client";
|
import { Station } from "../../generated/client";
|
||||||
import { PublicUser } from "./User";
|
import { PublicUser } from "./User";
|
||||||
|
|
||||||
export interface MissionStationLog {
|
export interface MissionStationLog {
|
||||||
@@ -6,11 +6,23 @@ export interface MissionStationLog {
|
|||||||
auto: true;
|
auto: true;
|
||||||
timeStamp: string;
|
timeStamp: string;
|
||||||
data: {
|
data: {
|
||||||
stationId: string;
|
stationId: number;
|
||||||
oldFMSstatus: string;
|
oldFMSstatus: string;
|
||||||
newFMSstatus: string;
|
newFMSstatus: string;
|
||||||
station: Station;
|
station: Station;
|
||||||
user: User;
|
user: PublicUser;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MissionSdsLog {
|
||||||
|
type: "sds-log";
|
||||||
|
auto: false;
|
||||||
|
timeStamp: string;
|
||||||
|
data: {
|
||||||
|
station: Station;
|
||||||
|
user: PublicUser;
|
||||||
|
stationId: number;
|
||||||
|
message: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,4 +37,4 @@ export interface MissionMessageLog {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MissionLog = MissionStationLog | MissionMessageLog;
|
export type MissionLog = MissionStationLog | MissionMessageLog | MissionSdsLog;
|
||||||
|
|||||||
Reference in New Issue
Block a user