feat: detail chart i18n

This commit is contained in:
hamster1963 2024-11-24 21:55:37 +08:00
parent ee03928a56
commit a949bf7e03
5 changed files with 68 additions and 11 deletions

View File

@ -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>

View File

@ -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 "
}, },

View File

@ -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": "主题-"
}, },

View File

@ -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": "主題-"
}, },

View File

@ -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>
); );
} }