feat: add txt export
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
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 { toast } from "react-toastify";
|
||||
|
||||
@@ -82,6 +82,7 @@ const parseJsonLogLine = (line: string) => {
|
||||
return { ts, level, msg, extraStr };
|
||||
}
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -180,6 +181,49 @@ export const DeviceLogsModal = ({
|
||||
return parsed;
|
||||
}, [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 (
|
||||
<Modal open={open} onClose={onClose} sx={{ width: "80vw", p: 3 }}>
|
||||
<div className="flex flex-col gap-6 h-[85vh]">
|
||||
@@ -188,7 +232,7 @@ export const DeviceLogsModal = ({
|
||||
<div className="flex gap-4 items-center">
|
||||
<TextField
|
||||
type="date"
|
||||
label="С"
|
||||
label="От"
|
||||
size="small"
|
||||
value={dateFrom}
|
||||
onChange={(e) => setDateFrom(e.target.value)}
|
||||
@@ -196,12 +240,20 @@ export const DeviceLogsModal = ({
|
||||
/>
|
||||
<TextField
|
||||
type="date"
|
||||
label="По"
|
||||
label="До"
|
||||
size="small"
|
||||
value={dateTo}
|
||||
onChange={(e) => setDateTo(e.target.value)}
|
||||
slotProps={{ inputLabel: { shrink: true } }}
|
||||
/>
|
||||
<Button
|
||||
variant="outlined"
|
||||
size="small"
|
||||
onClick={handleDownloadLogs}
|
||||
disabled={isLoading || Boolean(error) || logs.length === 0}
|
||||
>
|
||||
Скачать .txt
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user