fix: prettier config

This commit is contained in:
hamster1963
2024-12-13 17:26:28 +08:00
parent 1483ce56fa
commit 9a2f3ea8e6
81 changed files with 1666 additions and 2286 deletions

View File

@@ -1,12 +1,6 @@
"use client";
"use client"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import {
ChartConfig,
ChartContainer,
@@ -14,33 +8,28 @@ import {
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
import { fetchMonitor } from "@/lib/nezha-api";
import { formatTime } from "@/lib/utils";
import { formatRelativeTime } from "@/lib/utils";
import { useQuery } from "@tanstack/react-query";
import * as React from "react";
import { useCallback, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts";
import NetworkChartLoading from "./NetworkChartLoading";
import { NezhaMonitor, ServerMonitorChart } from "@/types/nezha-api";
import { Switch } from "./ui/switch";
import { Label } from "./ui/label";
} from "@/components/ui/chart"
import { fetchMonitor } from "@/lib/nezha-api"
import { formatTime } from "@/lib/utils"
import { formatRelativeTime } from "@/lib/utils"
import { NezhaMonitor, ServerMonitorChart } from "@/types/nezha-api"
import { useQuery } from "@tanstack/react-query"
import * as React from "react"
import { useCallback, useMemo } from "react"
import { useTranslation } from "react-i18next"
import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts"
import NetworkChartLoading from "./NetworkChartLoading"
import { Label } from "./ui/label"
import { Switch } from "./ui/switch"
interface ResultItem {
created_at: number;
[key: string]: number;
created_at: number
[key: string]: number
}
export function NetworkChart({
server_id,
show,
}: {
server_id: number;
show: boolean;
}) {
const { t } = useTranslation();
export function NetworkChart({ server_id, show }: { server_id: number; show: boolean }) {
const { t } = useTranslation()
const { data: monitorData } = useQuery({
queryKey: ["monitor", server_id],
@@ -49,29 +38,27 @@ export function NetworkChart({
refetchOnMount: true,
refetchOnWindowFocus: true,
refetchInterval: 10000,
});
})
if (!monitorData) return <NetworkChartLoading />;
if (!monitorData) return <NetworkChartLoading />
if (monitorData?.success && !monitorData.data) {
return (
<>
<div className="flex flex-col items-center justify-center">
<p className="text-sm font-medium opacity-40"></p>
<p className="text-sm font-medium opacity-40 mb-4">
{t("monitor.noData")}
</p>
<p className="text-sm font-medium opacity-40 mb-4">{t("monitor.noData")}</p>
</div>
<NetworkChartLoading />
</>
);
)
}
const transformedData = transformData(monitorData.data);
const transformedData = transformData(monitorData.data)
const formattedData = formatData(monitorData.data);
const formattedData = formatData(monitorData.data)
const chartDataKey = Object.keys(transformedData);
const chartDataKey = Object.keys(transformedData)
const initChartConfig = {
avg_delay: {
@@ -80,10 +67,10 @@ export function NetworkChart({
...chartDataKey.reduce((acc, key) => {
acc[key] = {
label: key,
};
return acc;
}
return acc
}, {} as ChartConfig),
} satisfies ChartConfig;
} satisfies ChartConfig
return (
<NetworkChartClient
@@ -93,7 +80,7 @@ export function NetworkChart({
serverName={monitorData.data[0].server_name}
formattedData={formattedData}
/>
);
)
}
export const NetworkChartClient = React.memo(function NetworkChart({
@@ -103,33 +90,33 @@ export const NetworkChartClient = React.memo(function NetworkChart({
serverName,
formattedData,
}: {
chartDataKey: string[];
chartConfig: ChartConfig;
chartData: ServerMonitorChart;
serverName: string;
formattedData: ResultItem[];
chartDataKey: string[]
chartConfig: ChartConfig
chartData: ServerMonitorChart
serverName: string
formattedData: ResultItem[]
}) {
const { t } = useTranslation();
const { t } = useTranslation()
const defaultChart = "All";
const defaultChart = "All"
const [activeChart, setActiveChart] = React.useState(defaultChart);
const [isPeakEnabled, setIsPeakEnabled] = React.useState(false);
const [activeChart, setActiveChart] = React.useState(defaultChart)
const [isPeakEnabled, setIsPeakEnabled] = React.useState(false)
const handleButtonClick = useCallback(
(chart: string) => {
setActiveChart((prev) => (prev === chart ? defaultChart : chart));
setActiveChart((prev) => (prev === chart ? defaultChart : chart))
},
[defaultChart],
);
)
const getColorByIndex = useCallback(
(chart: string) => {
const index = chartDataKey.indexOf(chart);
return `hsl(var(--chart-${(index % 10) + 1}))`;
const index = chartDataKey.indexOf(chart)
return `hsl(var(--chart-${(index % 10) + 1}))`
},
[chartDataKey],
);
)
const chartButtons = useMemo(
() =>
@@ -140,16 +127,14 @@ export const NetworkChartClient = React.memo(function NetworkChart({
className={`relative z-30 flex cursor-pointer grow basis-0 flex-col justify-center gap-1 border-b border-neutral-200 dark:border-neutral-800 px-6 py-4 text-left data-[active=true]:bg-muted/50 sm:border-l sm:border-t-0 sm:px-6`}
onClick={() => handleButtonClick(key)}
>
<span className="whitespace-nowrap text-xs text-muted-foreground">
{key}
</span>
<span className="whitespace-nowrap text-xs text-muted-foreground">{key}</span>
<span className="text-md font-bold leading-none sm:text-lg">
{chartData[key][chartData[key].length - 1].avg_delay.toFixed(2)}ms
</span>
</button>
)),
[chartDataKey, activeChart, chartData, handleButtonClick],
);
)
const chartLines = useMemo(() => {
if (activeChart !== defaultChart) {
@@ -162,7 +147,7 @@ export const NetworkChartClient = React.memo(function NetworkChart({
dataKey="avg_delay"
stroke={getColorByIndex(activeChart)}
/>
);
)
}
return chartDataKey.map((key) => (
<Line
@@ -175,65 +160,50 @@ export const NetworkChartClient = React.memo(function NetworkChart({
stroke={getColorByIndex(key)}
connectNulls={true}
/>
));
}, [activeChart, defaultChart, chartDataKey, getColorByIndex]);
))
}, [activeChart, defaultChart, chartDataKey, getColorByIndex])
const processedData = useMemo(() => {
if (!isPeakEnabled) {
return activeChart === defaultChart
? formattedData
: chartData[activeChart];
return activeChart === defaultChart ? formattedData : chartData[activeChart]
}
// 如果开启了削峰,对数据进行处理
const data = (
activeChart === defaultChart ? formattedData : chartData[activeChart]
) as ResultItem[];
const windowSize = 7; // 增加到7个点的移动平均
const weights = [0.1, 0.1, 0.15, 0.3, 0.15, 0.1, 0.1]; // 加权平均的权重
) as ResultItem[]
const windowSize = 7 // 增加到7个点的移动平均
const weights = [0.1, 0.1, 0.15, 0.3, 0.15, 0.1, 0.1] // 加权平均的权重
return data.map((point, index) => {
if (index < windowSize - 1) return point;
if (index < windowSize - 1) return point
const window = data.slice(index - windowSize + 1, index + 1);
const smoothed = { ...point } as ResultItem;
const window = data.slice(index - windowSize + 1, index + 1)
const smoothed = { ...point } as ResultItem
if (activeChart === defaultChart) {
// 处理所有线路的数据
chartDataKey.forEach((key) => {
const values = window
.map((w) => w[key])
.filter((v) => v !== undefined && v !== null) as number[];
.filter((v) => v !== undefined && v !== null) as number[]
if (values.length === windowSize) {
smoothed[key] = values.reduce(
(acc, val, idx) => acc + val * weights[idx],
0,
);
smoothed[key] = values.reduce((acc, val, idx) => acc + val * weights[idx], 0)
}
});
})
} else {
// 处理单条线路的数据
const values = window
.map((w) => w.avg_delay)
.filter((v) => v !== undefined && v !== null) as number[];
.filter((v) => v !== undefined && v !== null) as number[]
if (values.length === windowSize) {
smoothed.avg_delay = values.reduce(
(acc, val, idx) => acc + val * weights[idx],
0,
);
smoothed.avg_delay = values.reduce((acc, val, idx) => acc + val * weights[idx], 0)
}
}
return smoothed;
});
}, [
isPeakEnabled,
activeChart,
formattedData,
chartData,
chartDataKey,
defaultChart,
]);
return smoothed
})
}, [isPeakEnabled, activeChart, formattedData, chartData, chartDataKey, defaultChart])
return (
<Card>
@@ -246,11 +216,7 @@ export const NetworkChartClient = React.memo(function NetworkChart({
{chartDataKey.length} {t("monitor.monitorCount")}
</CardDescription>
<div className="flex items-center mt-0.5 space-x-2">
<Switch
id="Peak"
checked={isPeakEnabled}
onCheckedChange={setIsPeakEnabled}
/>
<Switch id="Peak" checked={isPeakEnabled} onCheckedChange={setIsPeakEnabled} />
<Label className="text-xs" htmlFor="Peak">
Peak cut
</Label>
@@ -259,15 +225,8 @@ export const NetworkChartClient = React.memo(function NetworkChart({
<div className="flex flex-wrap w-full">{chartButtons}</div>
</CardHeader>
<CardContent className="pr-2 pl-0 py-4 sm:pt-6 sm:pb-6 sm:pr-6 sm:pl-2">
<ChartContainer
config={chartConfig}
className="aspect-auto h-[250px] w-full"
>
<LineChart
accessibilityLayer
data={processedData}
margin={{ left: 12, right: 12 }}
>
<ChartContainer config={chartConfig} className="aspect-auto h-[250px] w-full">
<LineChart accessibilityLayer data={processedData} margin={{ left: 12, right: 12 }}>
<CartesianGrid vertical={false} />
<XAxis
dataKey="created_at"
@@ -292,67 +251,64 @@ export const NetworkChartClient = React.memo(function NetworkChart({
indicator={"line"}
labelKey="created_at"
labelFormatter={(_, payload) => {
return formatTime(payload[0].payload.created_at);
return formatTime(payload[0].payload.created_at)
}}
/>
}
/>
{activeChart === defaultChart && (
<ChartLegend content={<ChartLegendContent />} />
)}
{activeChart === defaultChart && <ChartLegend content={<ChartLegendContent />} />}
{chartLines}
</LineChart>
</ChartContainer>
</CardContent>
</Card>
);
});
)
})
const transformData = (data: NezhaMonitor[]) => {
const monitorData: ServerMonitorChart = {};
const monitorData: ServerMonitorChart = {}
data.forEach((item) => {
const monitorName = item.monitor_name;
const monitorName = item.monitor_name
if (!monitorData[monitorName]) {
monitorData[monitorName] = [];
monitorData[monitorName] = []
}
for (let i = 0; i < item.created_at.length; i++) {
monitorData[monitorName].push({
created_at: item.created_at[i],
avg_delay: item.avg_delay[i],
});
})
}
});
})
return monitorData;
};
return monitorData
}
const formatData = (rawData: NezhaMonitor[]) => {
const result: { [time: number]: ResultItem } = {};
const result: { [time: number]: ResultItem } = {}
const allTimes = new Set<number>();
const allTimes = new Set<number>()
rawData.forEach((item) => {
item.created_at.forEach((time) => allTimes.add(time));
});
item.created_at.forEach((time) => allTimes.add(time))
})
const allTimeArray = Array.from(allTimes).sort((a, b) => a - b);
const allTimeArray = Array.from(allTimes).sort((a, b) => a - b)
rawData.forEach((item) => {
const { monitor_name, created_at, avg_delay } = item;
const { monitor_name, created_at, avg_delay } = item
allTimeArray.forEach((time) => {
if (!result[time]) {
result[time] = { created_at: time };
result[time] = { created_at: time }
}
const timeIndex = created_at.indexOf(time);
const timeIndex = created_at.indexOf(time)
// @ts-expect-error - avg_delay is an array
result[time][monitor_name] =
timeIndex !== -1 ? avg_delay[timeIndex] : null;
});
});
result[time][monitor_name] = timeIndex !== -1 ? avg_delay[timeIndex] : null
})
})
return Object.values(result).sort((a, b) => a.created_at - b.created_at);
};
return Object.values(result).sort((a, b) => a.created_at - b.created_at)
}