mirror of
https://github.com/woodchen-ink/nezha-dash-v1.git
synced 2025-07-18 17:41:56 +08:00
fix: header link
This commit is contained in:
parent
4e34bcf239
commit
48b2d1493a
21
.github/ISSUE_TEMPLATE/bug-提交.md
vendored
21
.github/ISSUE_TEMPLATE/bug-提交.md
vendored
@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug 提交
|
|
||||||
about: 提交 bug,让面板变得更好。
|
|
||||||
title: "[BUG]"
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**面板版本(二选一)**
|
|
||||||
V0 | V1
|
|
||||||
|
|
||||||
**描述 bug**
|
|
||||||
在这里描述 bug 的相关信息
|
|
||||||
|
|
||||||
**屏幕截图**
|
|
||||||
有屏幕截图可以帮助更快定位到问题
|
|
||||||
|
|
||||||
|
|
||||||
**额外信息**
|
|
||||||
可附上其他需要的额外信息
|
|
15
.github/ISSUE_TEMPLATE/功能申请.md
vendored
15
.github/ISSUE_TEMPLATE/功能申请.md
vendored
@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
name: 功能申请
|
|
||||||
about: 描述需求
|
|
||||||
title: "[FEAT]"
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**面板版本(二选一)**
|
|
||||||
V0 | V1
|
|
||||||
|
|
||||||
**需要什么?**
|
|
||||||
|
|
||||||
**额外信息**
|
|
14
.github/ISSUE_TEMPLATE/改善建议.md
vendored
14
.github/ISSUE_TEMPLATE/改善建议.md
vendored
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
name: 改善建议
|
|
||||||
about: 交流面板需要改进的地方
|
|
||||||
title: "[SUGGEST]"
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**面板版本(二选一)**
|
|
||||||
V0 | V1
|
|
||||||
|
|
||||||
**需要改进的?**
|
|
||||||
*
|
|
10
package.json
10
package.json
@ -19,8 +19,8 @@
|
|||||||
"@radix-ui/react-progress": "^1.1.0",
|
"@radix-ui/react-progress": "^1.1.0",
|
||||||
"@radix-ui/react-separator": "^1.1.0",
|
"@radix-ui/react-separator": "^1.1.0",
|
||||||
"@radix-ui/react-slot": "^1.1.0",
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"@tanstack/react-query": "^5.61.5",
|
"@tanstack/react-query": "^5.62.0",
|
||||||
"@tanstack/react-query-devtools": "^5.61.5",
|
"@tanstack/react-query-devtools": "^5.62.0",
|
||||||
"@tanstack/react-table": "^8.20.5",
|
"@tanstack/react-table": "^8.20.5",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
@ -32,7 +32,7 @@
|
|||||||
"luxon": "^3.5.0",
|
"luxon": "^3.5.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-i18next": "^15.1.2",
|
"react-i18next": "^15.1.3",
|
||||||
"react-router-dom": "^7.0.1",
|
"react-router-dom": "^7.0.1",
|
||||||
"react-use-websocket": "^4.11.1",
|
"react-use-websocket": "^4.11.1",
|
||||||
"recharts": "^2.13.3",
|
"recharts": "^2.13.3",
|
||||||
@ -41,13 +41,13 @@
|
|||||||
"tailwindcss-animate": "^1.0.7"
|
"tailwindcss-animate": "^1.0.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.15.0",
|
"@eslint/js": "^9.16.0",
|
||||||
"@types/node": "^22.10.1",
|
"@types/node": "^22.10.1",
|
||||||
"@types/react": "^18.3.12",
|
"@types/react": "^18.3.12",
|
||||||
"@types/react-dom": "^18.3.1",
|
"@types/react-dom": "^18.3.1",
|
||||||
"@vitejs/plugin-react-swc": "^3.7.2",
|
"@vitejs/plugin-react-swc": "^3.7.2",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"eslint": "^9.15.0",
|
"eslint": "^9.16.0",
|
||||||
"eslint-plugin-react-hooks": "^5.0.0",
|
"eslint-plugin-react-hooks": "^5.0.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.14",
|
"eslint-plugin-react-refresh": "^0.4.14",
|
||||||
"globals": "^15.12.0",
|
"globals": "^15.12.0",
|
||||||
|
@ -49,6 +49,7 @@ function Header() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function DashboardLink() {
|
function DashboardLink() {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { data: userData } = useQuery({
|
const { data: userData } = useQuery({
|
||||||
queryKey: ["login-user"],
|
queryKey: ["login-user"],
|
||||||
queryFn: () => fetchLoginUser(),
|
queryFn: () => fetchLoginUser(),
|
||||||
@ -56,8 +57,6 @@ function DashboardLink() {
|
|||||||
refetchOnWindowFocus: true,
|
refetchOnWindowFocus: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!userData?.data?.id) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<a
|
<a
|
||||||
@ -66,7 +65,8 @@ function DashboardLink() {
|
|||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="flex items-center gap-1 text-sm font-medium opacity-50 transition-opacity hover:opacity-100"
|
className="flex items-center gap-1 text-sm font-medium opacity-50 transition-opacity hover:opacity-100"
|
||||||
>
|
>
|
||||||
Dashboard
|
{!userData?.data?.id && t("login")}
|
||||||
|
{userData?.data?.id && t("dashboard")}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -8,14 +8,16 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export default function ServerCard({
|
export default function ServerCard({
|
||||||
|
now,
|
||||||
serverInfo,
|
serverInfo,
|
||||||
}: {
|
}: {
|
||||||
|
now: number;
|
||||||
serverInfo: NezhaServer;
|
serverInfo: NezhaServer;
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { name, country_code, online, cpu, up, down, mem, stg } =
|
const { name, country_code, online, cpu, up, down, mem, stg } =
|
||||||
formatNezhaInfo(serverInfo);
|
formatNezhaInfo(now, serverInfo);
|
||||||
|
|
||||||
const showFlag = true;
|
const showFlag = true;
|
||||||
|
|
||||||
|
@ -77,20 +77,20 @@ export default function ServerDetailChart({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="grid md:grid-cols-2 lg:grid-cols-3 grid-cols-1 gap-3">
|
<section className="grid md:grid-cols-2 lg:grid-cols-3 grid-cols-1 gap-3">
|
||||||
<CpuChart data={server} />
|
<CpuChart now={nezhaWsData.now} data={server} />
|
||||||
<ProcessChart data={server} />
|
<ProcessChart now={nezhaWsData.now} data={server} />
|
||||||
<DiskChart data={server} />
|
<DiskChart now={nezhaWsData.now} data={server} />
|
||||||
<MemChart data={server} />
|
<MemChart now={nezhaWsData.now} data={server} />
|
||||||
<NetworkChart data={server} />
|
<NetworkChart now={nezhaWsData.now} data={server} />
|
||||||
<ConnectChart data={server} />
|
<ConnectChart now={nezhaWsData.now} data={server} />
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function CpuChart({ data }: { data: NezhaServer }) {
|
function CpuChart({ now,data }: { now: number;data: NezhaServer }) {
|
||||||
const [cpuChartData, setCpuChartData] = useState([] as cpuChartData[]);
|
const [cpuChartData, setCpuChartData] = useState([] as cpuChartData[]);
|
||||||
|
|
||||||
const { cpu } = formatNezhaInfo(data);
|
const { cpu } = formatNezhaInfo(now,data);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -183,13 +183,13 @@ function CpuChart({ data }: { data: NezhaServer }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ProcessChart({ data }: { data: NezhaServer }) {
|
function ProcessChart({ now, data }: { now: number; data: NezhaServer }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [processChartData, setProcessChartData] = useState(
|
const [processChartData, setProcessChartData] = useState(
|
||||||
[] as processChartData[],
|
[] as processChartData[],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { process } = formatNezhaInfo(data);
|
const { process } = formatNezhaInfo(now,data);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -276,11 +276,11 @@ function ProcessChart({ data }: { data: NezhaServer }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function MemChart({ data }: { data: NezhaServer }) {
|
function MemChart({ now,data }: { now: number;data: NezhaServer }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [memChartData, setMemChartData] = useState([] as memChartData[]);
|
const [memChartData, setMemChartData] = useState([] as memChartData[]);
|
||||||
|
|
||||||
const { mem, swap } = formatNezhaInfo(data);
|
const { mem, swap } = formatNezhaInfo(now,data);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -406,11 +406,11 @@ function MemChart({ data }: { data: NezhaServer }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function DiskChart({ data }: { data: NezhaServer }) {
|
function DiskChart({ now,data }: { now: number;data: NezhaServer }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [diskChartData, setDiskChartData] = useState([] as diskChartData[]);
|
const [diskChartData, setDiskChartData] = useState([] as diskChartData[]);
|
||||||
|
|
||||||
const { disk } = formatNezhaInfo(data);
|
const { disk } = formatNezhaInfo(now,data);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -503,13 +503,13 @@ function DiskChart({ data }: { data: NezhaServer }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function NetworkChart({ data }: { data: NezhaServer }) {
|
function NetworkChart({ now,data }: { now: number;data: NezhaServer }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [networkChartData, setNetworkChartData] = useState(
|
const [networkChartData, setNetworkChartData] = useState(
|
||||||
[] as networkChartData[],
|
[] as networkChartData[],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { up, down } = formatNezhaInfo(data);
|
const { up, down } = formatNezhaInfo(now,data);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -632,12 +632,12 @@ function NetworkChart({ data }: { data: NezhaServer }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ConnectChart({ data }: { data: NezhaServer }) {
|
function ConnectChart({ now,data }: { now: number;data: NezhaServer }) {
|
||||||
const [connectChartData, setConnectChartData] = useState(
|
const [connectChartData, setConnectChartData] = useState(
|
||||||
[] as connectChartData[],
|
[] as connectChartData[],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { tcp, udp } = formatNezhaInfo(data);
|
const { tcp, udp } = formatNezhaInfo(now,data);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
|
@ -37,7 +37,7 @@ export default function ServerDetailOverview({
|
|||||||
return <ServerDetailLoading />;
|
return <ServerDetailLoading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { name, online, uptime, version } = formatNezhaInfo(server);
|
const { name, online, uptime, version } = formatNezhaInfo(nezhaWsData.now,server);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -6,7 +6,7 @@ export function cn(...inputs: ClassValue[]) {
|
|||||||
return twMerge(clsx(inputs));
|
return twMerge(clsx(inputs));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatNezhaInfo(serverInfo: NezhaServer) {
|
export function formatNezhaInfo(now: number,serverInfo: NezhaServer) {
|
||||||
const lastActiveTime = parseISOTimestamp(serverInfo.last_active);
|
const lastActiveTime = parseISOTimestamp(serverInfo.last_active);
|
||||||
return {
|
return {
|
||||||
...serverInfo,
|
...serverInfo,
|
||||||
@ -14,7 +14,7 @@ export function formatNezhaInfo(serverInfo: NezhaServer) {
|
|||||||
process: serverInfo.state.process_count || 0,
|
process: serverInfo.state.process_count || 0,
|
||||||
up: serverInfo.state.net_out_speed / 1024 / 1024 || 0,
|
up: serverInfo.state.net_out_speed / 1024 / 1024 || 0,
|
||||||
down: serverInfo.state.net_in_speed / 1024 / 1024 || 0,
|
down: serverInfo.state.net_in_speed / 1024 / 1024 || 0,
|
||||||
online: Date.now() - lastActiveTime <= 30000,
|
online: now - lastActiveTime <= 30000,
|
||||||
uptime: serverInfo.state.uptime || 0,
|
uptime: serverInfo.state.uptime || 0,
|
||||||
version: serverInfo.host.version || null,
|
version: serverInfo.host.version || null,
|
||||||
tcp: serverInfo.state.tcp_conn_count || 0,
|
tcp: serverInfo.state.tcp_conn_count || 0,
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"nezha": "Nezha Monitoring",
|
"nezha": "Nezha Monitoring",
|
||||||
"overview": "Overview",
|
"overview": "Overview",
|
||||||
|
"dashboard": "Dashboard",
|
||||||
|
"login": "Login",
|
||||||
"whereTheTimeIs": "Where the time is",
|
"whereTheTimeIs": "Where the time is",
|
||||||
"info": {
|
"info": {
|
||||||
"websocketConnecting": "WebSocket connecting",
|
"websocketConnecting": "WebSocket connecting",
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"nezha": "哪吒监控",
|
"nezha": "哪吒监控",
|
||||||
"overview": "概览",
|
"overview": "概览",
|
||||||
|
"dashboard": "管理后台",
|
||||||
|
"login": "登录",
|
||||||
"whereTheTimeIs": "当前时间",
|
"whereTheTimeIs": "当前时间",
|
||||||
"info": {
|
"info": {
|
||||||
"websocketConnecting": "WebSocket 连接中",
|
"websocketConnecting": "WebSocket 连接中",
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"nezha": "哪吒監控",
|
"nezha": "哪吒監控",
|
||||||
"overview": "概覽",
|
"overview": "概覽",
|
||||||
|
"dashboard": "管理後台",
|
||||||
|
"login": "登錄",
|
||||||
"whereTheTimeIs": "目前時間",
|
"whereTheTimeIs": "目前時間",
|
||||||
"info": {
|
"info": {
|
||||||
"websocketConnecting": "WebSocket 連接中",
|
"websocketConnecting": "WebSocket 連接中",
|
||||||
|
@ -57,10 +57,10 @@ export default function Servers() {
|
|||||||
|
|
||||||
const totalServers = nezhaWsData?.servers?.length || 0;
|
const totalServers = nezhaWsData?.servers?.length || 0;
|
||||||
const onlineServers =
|
const onlineServers =
|
||||||
nezhaWsData?.servers?.filter((server) => formatNezhaInfo(server).online)
|
nezhaWsData?.servers?.filter((server) => formatNezhaInfo(nezhaWsData.now,server).online)
|
||||||
?.length || 0;
|
?.length || 0;
|
||||||
const offlineServers =
|
const offlineServers =
|
||||||
nezhaWsData?.servers?.filter((server) => !formatNezhaInfo(server).online)
|
nezhaWsData?.servers?.filter((server) => !formatNezhaInfo(nezhaWsData.now,server).online)
|
||||||
?.length || 0;
|
?.length || 0;
|
||||||
const up =
|
const up =
|
||||||
nezhaWsData?.servers?.reduce(
|
nezhaWsData?.servers?.reduce(
|
||||||
@ -112,7 +112,7 @@ export default function Servers() {
|
|||||||
{showServices && <ServiceTracker />}
|
{showServices && <ServiceTracker />}
|
||||||
<section className="grid grid-cols-1 gap-2 md:grid-cols-2 mt-6">
|
<section className="grid grid-cols-1 gap-2 md:grid-cols-2 mt-6">
|
||||||
{filteredServers.map((serverInfo) => (
|
{filteredServers.map((serverInfo) => (
|
||||||
<ServerCard key={serverInfo.id} serverInfo={serverInfo} />
|
<ServerCard now={nezhaWsData.now} key={serverInfo.id} serverInfo={serverInfo} />
|
||||||
))}
|
))}
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user