mirror of
https://github.com/woodchen-ink/nezha-dash-v1.git
synced 2025-07-18 17:41:56 +08:00
feat: detail chart i18n
This commit is contained in:
parent
ee03928a56
commit
a949bf7e03
@ -16,6 +16,7 @@ import {
|
|||||||
import { ServerDetailChartLoading } from "./loading/ServerDetailLoading";
|
import { ServerDetailChartLoading } from "./loading/ServerDetailLoading";
|
||||||
import AnimatedCircularProgressBar from "./ui/animated-circular-progress-bar";
|
import AnimatedCircularProgressBar from "./ui/animated-circular-progress-bar";
|
||||||
import { useWebSocketContext } from "@/hooks/use-websocket-context";
|
import { useWebSocketContext } from "@/hooks/use-websocket-context";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type cpuChartData = {
|
type cpuChartData = {
|
||||||
timeStamp: string;
|
timeStamp: string;
|
||||||
@ -54,12 +55,10 @@ export default function ServerDetailChart() {
|
|||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const { lastMessage, readyState } = useWebSocketContext();
|
const { lastMessage, readyState } = useWebSocketContext();
|
||||||
|
|
||||||
// 检查连接状态
|
|
||||||
if (readyState !== 1) {
|
if (readyState !== 1) {
|
||||||
return <ServerDetailChartLoading />;
|
return <ServerDetailChartLoading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析消息
|
|
||||||
const nezhaWsData = lastMessage
|
const nezhaWsData = lastMessage
|
||||||
? (JSON.parse(lastMessage.data) as NezhaAPIResponse)
|
? (JSON.parse(lastMessage.data) as NezhaAPIResponse)
|
||||||
: null;
|
: null;
|
||||||
@ -183,6 +182,7 @@ function CpuChart({ data }: { data: NezhaAPI }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ProcessChart({ data }: { data: NezhaAPI }) {
|
function ProcessChart({ data }: { data: NezhaAPI }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [processChartData, setProcessChartData] = useState(
|
const [processChartData, setProcessChartData] = useState(
|
||||||
[] as processChartData[],
|
[] as processChartData[],
|
||||||
);
|
);
|
||||||
@ -222,7 +222,9 @@ function ProcessChart({ data }: { data: NezhaAPI }) {
|
|||||||
<CardContent className="px-6 py-3">
|
<CardContent className="px-6 py-3">
|
||||||
<section className="flex flex-col gap-1">
|
<section className="flex flex-col gap-1">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<p className="text-md font-medium">{"Process"}</p>
|
<p className="text-md font-medium">
|
||||||
|
{t("serverDetailChart.process")}
|
||||||
|
</p>
|
||||||
<section className="flex items-center gap-2">
|
<section className="flex items-center gap-2">
|
||||||
<p className="text-xs text-end w-10 font-medium">{process}</p>
|
<p className="text-xs text-end w-10 font-medium">{process}</p>
|
||||||
</section>
|
</section>
|
||||||
@ -273,6 +275,7 @@ function ProcessChart({ data }: { data: NezhaAPI }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function MemChart({ data }: { data: NezhaAPI }) {
|
function MemChart({ data }: { data: NezhaAPI }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [memChartData, setMemChartData] = useState([] as memChartData[]);
|
const [memChartData, setMemChartData] = useState([] as memChartData[]);
|
||||||
|
|
||||||
const { mem, swap } = formatNezhaInfo(data);
|
const { mem, swap } = formatNezhaInfo(data);
|
||||||
@ -315,7 +318,9 @@ function MemChart({ data }: { data: NezhaAPI }) {
|
|||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<section className="flex items-center gap-4">
|
<section className="flex items-center gap-4">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<p className=" text-xs text-muted-foreground">{"Mem"}</p>
|
<p className=" text-xs text-muted-foreground">
|
||||||
|
{t("serverDetailChart.mem")}
|
||||||
|
</p>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<AnimatedCircularProgressBar
|
<AnimatedCircularProgressBar
|
||||||
className="size-3 text-[0px]"
|
className="size-3 text-[0px]"
|
||||||
@ -328,7 +333,9 @@ function MemChart({ data }: { data: NezhaAPI }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<p className=" text-xs text-muted-foreground">{"Swap"}</p>
|
<p className=" text-xs text-muted-foreground">
|
||||||
|
{t("serverDetailChart.swap")}
|
||||||
|
</p>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<AnimatedCircularProgressBar
|
<AnimatedCircularProgressBar
|
||||||
className="size-3 text-[0px]"
|
className="size-3 text-[0px]"
|
||||||
@ -398,6 +405,7 @@ function MemChart({ data }: { data: NezhaAPI }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function DiskChart({ data }: { data: NezhaAPI }) {
|
function DiskChart({ data }: { data: NezhaAPI }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [diskChartData, setDiskChartData] = useState([] as diskChartData[]);
|
const [diskChartData, setDiskChartData] = useState([] as diskChartData[]);
|
||||||
|
|
||||||
const { disk } = formatNezhaInfo(data);
|
const { disk } = formatNezhaInfo(data);
|
||||||
@ -432,7 +440,7 @@ function DiskChart({ data }: { data: NezhaAPI }) {
|
|||||||
<CardContent className="px-6 py-3">
|
<CardContent className="px-6 py-3">
|
||||||
<section className="flex flex-col gap-1">
|
<section className="flex flex-col gap-1">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<p className="text-md font-medium">{"Disk"}</p>
|
<p className="text-md font-medium">{t("serverDetailChart.disk")}</p>
|
||||||
<section className="flex items-center gap-2">
|
<section className="flex items-center gap-2">
|
||||||
<p className="text-xs text-end w-10 font-medium">
|
<p className="text-xs text-end w-10 font-medium">
|
||||||
{disk.toFixed(0)}%
|
{disk.toFixed(0)}%
|
||||||
@ -494,6 +502,7 @@ function DiskChart({ data }: { data: NezhaAPI }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function NetworkChart({ data }: { data: NezhaAPI }) {
|
function NetworkChart({ data }: { data: NezhaAPI }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [networkChartData, setNetworkChartData] = useState(
|
const [networkChartData, setNetworkChartData] = useState(
|
||||||
[] as networkChartData[],
|
[] as networkChartData[],
|
||||||
);
|
);
|
||||||
@ -544,14 +553,18 @@ function NetworkChart({ data }: { data: NezhaAPI }) {
|
|||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<section className="flex items-center gap-4">
|
<section className="flex items-center gap-4">
|
||||||
<div className="flex flex-col w-20">
|
<div className="flex flex-col w-20">
|
||||||
<p className="text-xs text-muted-foreground">{"Upload"}</p>
|
<p className="text-xs text-muted-foreground">
|
||||||
|
{t("serverDetailChart.upload")}
|
||||||
|
</p>
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<span className="relative inline-flex size-1.5 rounded-full bg-[hsl(var(--chart-1))]"></span>
|
<span className="relative inline-flex size-1.5 rounded-full bg-[hsl(var(--chart-1))]"></span>
|
||||||
<p className="text-xs font-medium">{up.toFixed(2)} M/s</p>
|
<p className="text-xs font-medium">{up.toFixed(2)} M/s</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col w-20">
|
<div className="flex flex-col w-20">
|
||||||
<p className=" text-xs text-muted-foreground">{"Download"}</p>
|
<p className=" text-xs text-muted-foreground">
|
||||||
|
{t("serverDetailChart.download")}
|
||||||
|
</p>
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<span className="relative inline-flex size-1.5 rounded-full bg-[hsl(var(--chart-4))]"></span>
|
<span className="relative inline-flex size-1.5 rounded-full bg-[hsl(var(--chart-4))]"></span>
|
||||||
<p className="text-xs font-medium">{down.toFixed(2)} M/s</p>
|
<p className="text-xs font-medium">{down.toFixed(2)} M/s</p>
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
"nezha": "Nezha Monitoring",
|
"nezha": "Nezha Monitoring",
|
||||||
"overview": "Overview",
|
"overview": "Overview",
|
||||||
"whereTheTimeIs": "Where the time is",
|
"whereTheTimeIs": "Where the time is",
|
||||||
|
"info": {
|
||||||
|
"websocketConnecting": "WebSocket connecting",
|
||||||
|
"websocketConnected": "WebSocket connected",
|
||||||
|
"websocketDisconnected": "WebSocket disconnected",
|
||||||
|
"processing": "Processing..."
|
||||||
|
},
|
||||||
"serverOverview": {
|
"serverOverview": {
|
||||||
"totalServers": "Total Servers",
|
"totalServers": "Total Servers",
|
||||||
"onlineServers": "Online Servers",
|
"onlineServers": "Online Servers",
|
||||||
@ -27,6 +33,14 @@
|
|||||||
"region": "Region",
|
"region": "Region",
|
||||||
"system": "System"
|
"system": "System"
|
||||||
},
|
},
|
||||||
|
"serverDetailChart": {
|
||||||
|
"process": "Process",
|
||||||
|
"disk": "Disk",
|
||||||
|
"mem": "Mem",
|
||||||
|
"swap": "Swap",
|
||||||
|
"upload": "Upload",
|
||||||
|
"download": "Download"
|
||||||
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"themeBy": "Theme by "
|
"themeBy": "Theme by "
|
||||||
},
|
},
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
"nezha": "哪吒监控",
|
"nezha": "哪吒监控",
|
||||||
"overview": "概览",
|
"overview": "概览",
|
||||||
"whereTheTimeIs": "当前时间",
|
"whereTheTimeIs": "当前时间",
|
||||||
|
"info": {
|
||||||
|
"websocketConnecting": "WebSocket 连接中",
|
||||||
|
"websocketConnected": "WebSocket 连接成功",
|
||||||
|
"websocketDisconnected": "WebSocket 连接断开",
|
||||||
|
"processing": "处理中..."
|
||||||
|
},
|
||||||
"serverOverview": {
|
"serverOverview": {
|
||||||
"totalServers": "服务器总数",
|
"totalServers": "服务器总数",
|
||||||
"onlineServers": "在线服务器",
|
"onlineServers": "在线服务器",
|
||||||
@ -27,6 +33,14 @@
|
|||||||
"region": "区域",
|
"region": "区域",
|
||||||
"system": "系统"
|
"system": "系统"
|
||||||
},
|
},
|
||||||
|
"serverDetailChart": {
|
||||||
|
"process": "进程数",
|
||||||
|
"disk": "磁盘",
|
||||||
|
"mem": "内存",
|
||||||
|
"swap": "虚拟内存",
|
||||||
|
"upload": "上传",
|
||||||
|
"download": "下载"
|
||||||
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"themeBy": "主题-"
|
"themeBy": "主题-"
|
||||||
},
|
},
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
"nezha": "哪吒監控",
|
"nezha": "哪吒監控",
|
||||||
"overview": "概覽",
|
"overview": "概覽",
|
||||||
"whereTheTimeIs": "目前時間",
|
"whereTheTimeIs": "目前時間",
|
||||||
|
"info": {
|
||||||
|
"websocketConnecting": "WebSocket 連接中",
|
||||||
|
"websocketConnected": "WebSocket 連接成功",
|
||||||
|
"websocketDisconnected": "WebSocket 連接斷開",
|
||||||
|
"processing": "處理中..."
|
||||||
|
},
|
||||||
"serverOverview": {
|
"serverOverview": {
|
||||||
"totalServers": "總服務器",
|
"totalServers": "總服務器",
|
||||||
"onlineServers": "線上服務器",
|
"onlineServers": "線上服務器",
|
||||||
@ -27,6 +33,14 @@
|
|||||||
"region": "地區",
|
"region": "地區",
|
||||||
"system": "系統"
|
"system": "系統"
|
||||||
},
|
},
|
||||||
|
"serverDetailChart": {
|
||||||
|
"process": "進程數",
|
||||||
|
"disk": "磁盤",
|
||||||
|
"mem": "內存",
|
||||||
|
"swap": "虛擬記憶體",
|
||||||
|
"upload": "上傳",
|
||||||
|
"download": "下載"
|
||||||
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"themeBy": "主題-"
|
"themeBy": "主題-"
|
||||||
},
|
},
|
||||||
|
@ -9,8 +9,10 @@ import { fetchServerGroup } from "@/lib/nezha-api";
|
|||||||
import GroupSwitch from "@/components/GroupSwitch";
|
import GroupSwitch from "@/components/GroupSwitch";
|
||||||
import { ServerGroup } from "@/types/nezha-api";
|
import { ServerGroup } from "@/types/nezha-api";
|
||||||
import { useWebSocketContext } from "@/hooks/use-websocket-context";
|
import { useWebSocketContext } from "@/hooks/use-websocket-context";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export default function Servers() {
|
export default function Servers() {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { data: groupData } = useQuery({
|
const { data: groupData } = useQuery({
|
||||||
queryKey: ["server-group"],
|
queryKey: ["server-group"],
|
||||||
queryFn: () => fetchServerGroup(),
|
queryFn: () => fetchServerGroup(),
|
||||||
@ -26,14 +28,14 @@ export default function Servers() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (readyState == 1) {
|
if (readyState == 1) {
|
||||||
toast.success("WebSocket connected");
|
toast.success(t("info.websocketConnected"));
|
||||||
}
|
}
|
||||||
}, [readyState]);
|
}, [readyState]);
|
||||||
|
|
||||||
if (readyState !== 1) {
|
if (readyState !== 1) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center ">
|
<div className="flex flex-col items-center justify-center ">
|
||||||
<p className="font-semibold text-sm">connecting...</p>
|
<p className="font-semibold text-sm">{t("info.websocketConnecting")}</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -45,7 +47,7 @@ export default function Servers() {
|
|||||||
if (!nezhaWsData) {
|
if (!nezhaWsData) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center ">
|
<div className="flex flex-col items-center justify-center ">
|
||||||
<p className="font-semibold text-sm">processing...</p>
|
<p className="font-semibold text-sm">{t("info.processing")}</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user