feat: add txt export

This commit is contained in:
2026-02-22 19:37:02 +03:00
parent 1c097a4ca2
commit 2a9449ba58

View File

@@ -1,5 +1,5 @@
import { API_URL, authInstance, Modal } from "@shared"; import { API_URL, authInstance, Modal } from "@shared";
import { CircularProgress, TextField } from "@mui/material"; import { Button, CircularProgress, TextField } from "@mui/material";
import { useEffect, useState, useMemo } from "react"; import { useEffect, useState, useMemo } from "react";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
@@ -82,6 +82,7 @@ const parseJsonLogLine = (line: string) => {
return { ts, level, msg, extraStr }; return { ts, level, msg, extraStr };
} }
} catch { } catch {
return null;
} }
return null; return null;
}; };
@@ -180,6 +181,49 @@ export const DeviceLogsModal = ({
return parsed; return parsed;
}, [chunks]); }, [chunks]);
const logsText = useMemo(
() =>
logs
.map((log) => {
const level = log.level === "unknown" ? "LOG" : log.level.toUpperCase();
const time = log.time ? `[${log.time}] ` : "";
return `${time}${level}: ${log.text}`;
})
.join("\n"),
[logs]
);
const handleDownloadLogs = () => {
if (!logsText) {
toast.info("Нет логов для сохранения");
return;
}
try {
const safeDeviceUuid = (deviceUuid ?? "device").replace(
/[^a-zA-Z0-9_-]/g,
"_"
);
const fileName = `logs_${safeDeviceUuid}_${dateFrom}_${dateTo}.txt`;
const blob = new Blob([`\uFEFF${logsText}`], {
type: "text/plain;charset=utf-8",
});
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
toast.success("Логи сохранены в .txt");
} catch {
toast.error("Не удалось сохранить логи");
}
};
return ( return (
<Modal open={open} onClose={onClose} sx={{ width: "80vw", p: 3 }}> <Modal open={open} onClose={onClose} sx={{ width: "80vw", p: 3 }}>
<div className="flex flex-col gap-6 h-[85vh]"> <div className="flex flex-col gap-6 h-[85vh]">
@@ -188,7 +232,7 @@ export const DeviceLogsModal = ({
<div className="flex gap-4 items-center"> <div className="flex gap-4 items-center">
<TextField <TextField
type="date" type="date"
label="С" label="От"
size="small" size="small"
value={dateFrom} value={dateFrom}
onChange={(e) => setDateFrom(e.target.value)} onChange={(e) => setDateFrom(e.target.value)}
@@ -196,12 +240,20 @@ export const DeviceLogsModal = ({
/> />
<TextField <TextField
type="date" type="date"
label="По" label="До"
size="small" size="small"
value={dateTo} value={dateTo}
onChange={(e) => setDateTo(e.target.value)} onChange={(e) => setDateTo(e.target.value)}
slotProps={{ inputLabel: { shrink: true } }} slotProps={{ inputLabel: { shrink: true } }}
/> />
<Button
variant="outlined"
size="small"
onClick={handleDownloadLogs}
disabled={isLoading || Boolean(error) || logs.length === 0}
>
Скачать .txt
</Button>
</div> </div>
</div> </div>