feat: show deployment platform in system info

This commit is contained in:
tianma-if committed 2026-08-20 23:41:30 +08:00
1 parent b76723314d
commit 254b46a8ed
6 files changed
+74 -2

No files matched your search

@@ -1,9 +1,12 @@
import { useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { CircleCheck, Copy, ExternalLink } from "lucide-react";
import { Trans, useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import { useDeployedUpdateNotice } from "@/hooks/useDeployedUpdateNotice";
import { detectWebClientKind } from "@/lib/client-environment";
import { api, getConfiguredDesktopApiBaseUrl } from "@/lib/api";
import { resolveDeploymentPlatform } from "@/lib/instance-runtime";
import { cn } from "@/lib/utils";
import { getReleaseTagForVersion, resolveLocalizedReleaseChanges } from "@/lib/version-check";
import { copyTextToClipboard } from "./settings-utils";
@@ -36,7 +39,11 @@ const getDeploymentDescription = (t: (key: string) => string) => {
return `${trigger} · ${method}`;
};
export const getWebSystemInfoItems = (t: (key: string) => string, language: string): SystemInfoItem[] => {
export const getWebSystemInfoItems = (
t: (key: string) => string,
language: string,
instanceRuntime?: string | null,
): SystemInfoItem[] => {
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone || t("systemInfo.unknown");
const userAgent = navigator.userAgent;
const clientKind = detectWebClientKind({
@@ -57,6 +64,10 @@ export const getWebSystemInfoItems = (t: (key: string) => string, language: stri
},
{ label: t("systemInfo.build"), value: __EDGEEVER_BUILD_LABEL__ },
{ label: t("systemInfo.client"), value: t(`systemInfo.clients.${clientKind}`) },
{
label: t("systemInfo.deploymentPlatform"),
value: t(`systemInfo.deploymentPlatforms.${resolveDeploymentPlatform(instanceRuntime)}`),
},
{ label: t("systemInfo.deployment"), value: getDeploymentDescription(t) },
...(clientKind === "desktopApp"
? []
@@ -71,7 +82,18 @@ export const SystemInfoPanel = ({ active = true }: { active?: boolean }) => {
const { t, i18n } = useTranslation();
const [copied, setCopied] = useState(false);
const { release } = useDeployedUpdateNotice();
const infoItems = useMemo(() => getWebSystemInfoItems(t, i18n.language), [i18n.language, t]);
const instanceUrl = window.edgeeverDesktop?.isAvailable === true ? getConfiguredDesktopApiBaseUrl() : window.location.origin;
const healthQuery = useQuery({
queryKey: ["instance-health", instanceUrl],
queryFn: () => api.getInstanceHealth(),
enabled: active && Boolean(instanceUrl),
staleTime: 5 * 60 * 1000,
retry: 1,
});
const infoItems = useMemo(
() => getWebSystemInfoItems(t, i18n.language, healthQuery.data?.runtime),
[healthQuery.data?.runtime, i18n.language, t],
);
const releaseTag = release ? getReleaseTagForVersion(release.version) : null;
const releaseHighlights = resolveLocalizedReleaseChanges(
release?.changes ?? {},
+9
View File
@@ -51,6 +51,13 @@ export type InstanceRelease = {
changes: Record<string, string[]>;
};
export type InstanceHealth = {
ok: true;
name: string;
runtime: string;
authMode: string;
};
type ListMemosResponse = {
memos: MemoSummary[];
totalCount: number;
@@ -457,6 +464,8 @@ const requestArrayBuffer = async (path: string) => {
};
export const api = {
getInstanceHealth: () => request<InstanceHealth>("/api/health"),
getInstanceRelease: () => request<InstanceRelease>("/api/release"),
getSession: () => request<AuthSession>("/api/v1/auth/session"),
@@ -0,0 +1,17 @@
import { describe, expect, test } from "bun:test";
import { resolveDeploymentPlatform } from "./instance-runtime.ts";
describe("resolveDeploymentPlatform", () => {
test("maps the Cloudflare Workers runtime", () => {
expect(resolveDeploymentPlatform("cloudflare-workers")).toBe("cloudflare");
});
test("maps the self-hosted Bun runtime to Docker", () => {
expect(resolveDeploymentPlatform("self-hosted-bun")).toBe("docker");
});
test("keeps missing and future runtimes explicit", () => {
expect(resolveDeploymentPlatform(undefined)).toBe("unknown");
expect(resolveDeploymentPlatform("future-runtime")).toBe("unknown");
});
});
+12
View File
@@ -0,0 +1,12 @@
export type DeploymentPlatform = "cloudflare" | "docker" | "unknown";
export const resolveDeploymentPlatform = (runtime: string | null | undefined): DeploymentPlatform => {
switch (runtime) {
case "cloudflare-workers":
return "cloudflare";
case "self-hosted-bun":
return "docker";
default:
return "unknown";
}
};
+6
View File
@@ -559,6 +559,12 @@ export const enUS = {
pwa: "PWA",
web: "Web",
},
deploymentPlatform: "Deployment platform",
deploymentPlatforms: {
cloudflare: "Cloudflare",
docker: "Docker",
unknown: "Unknown",
},
deployment: "Deployment",
deploymentTriggers: {
github_release: "GitHub Release trigger",
+6
View File
@@ -559,6 +559,12 @@ export const zhCN = {
pwa: "PWA",
web: "网页",
},
deploymentPlatform: "部署平台",
deploymentPlatforms: {
cloudflare: "Cloudflare",
docker: "Docker",
unknown: "未知",
},
deployment: "自动部署方式",
deploymentTriggers: {
github_release: "正式 Release 触发",