feat(web): display backend version info in sidebar (#2087)

* feat(web): display backend version info in sidebar

* fix(web): improve version parsing and timeout behavior

* refactor(web): remove useless --version fallback

* feat(web): implement version info caching and improve retrieval logic

* fix(web): clarify version timeout rationale

* fix(web): harden gateway version probing and tests

* style(web): split regexp to two lines for lint
This commit is contained in:
LC
2026-03-30 16:44:50 +08:00
committed by GitHub
parent e88df4ff9c
commit ff0266a40e
8 changed files with 725 additions and 5 deletions
+11
View File
@@ -13,6 +13,13 @@ export interface LauncherConfig {
allowed_cidrs: string[]
}
export interface SystemVersionInfo {
version: string
git_commit?: string
build_time?: string
go_version: string
}
async function request<T>(path: string, options?: RequestInit): Promise<T> {
const res = await launcherFetch(path, options)
if (!res.ok) {
@@ -62,3 +69,7 @@ export async function setLauncherConfig(
body: JSON.stringify(payload),
})
}
export async function getSystemVersionInfo(): Promise<SystemVersionInfo> {
return request<SystemVersionInfo>("/api/system/version")
}
@@ -10,10 +10,12 @@ import {
IconSparkles,
IconTools,
} from "@tabler/icons-react"
import { useQuery } from "@tanstack/react-query"
import { Link, useRouterState } from "@tanstack/react-router"
import * as React from "react"
import { useTranslation } from "react-i18next"
import { getSystemVersionInfo } from "@/api/system"
import {
Collapsible,
CollapsibleContent,
@@ -27,6 +29,7 @@ import {
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarFooter,
SidebarMenuItem,
SidebarRail,
} from "@/components/ui/sidebar"
@@ -78,6 +81,13 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
language: (i18n.resolvedLanguage ?? i18n.language ?? "").toLowerCase(),
t,
})
const { data: versionInfo } = useQuery({
queryKey: ["system", "version"],
queryFn: getSystemVersionInfo,
staleTime: 5 * 60 * 1000,
})
const versionText = versionInfo?.version ?? t("footer.version_unknown")
const navGroups: NavGroup[] = React.useMemo(() => {
return [
@@ -235,6 +245,26 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
</Collapsible>
))}
</SidebarContent>
<SidebarFooter className="border-t-border/30 group-data-[collapsible=icon]:hidden border-t px-3 py-2">
<div className="text-muted-foreground flex flex-col gap-0.5 text-[11px] leading-4">
<div className="truncate" title={versionText}>
<span className="text-foreground/80">{t("footer.version")}:</span>{" "}
{versionText}
</div>
{versionInfo?.git_commit && (
<div className="truncate" title={versionInfo.git_commit}>
<span className="text-foreground/80">{t("footer.commit")}:</span>{" "}
{versionInfo.git_commit}
</div>
)}
{versionInfo?.build_time && (
<div className="truncate" title={versionInfo.build_time}>
<span className="text-foreground/80">{t("footer.build")}:</span>{" "}
{versionInfo.build_time}
</div>
)}
</div>
</SidebarFooter>
<SidebarRail />
</Sidebar>
)
+6
View File
@@ -93,6 +93,12 @@
"labels": {
"loading": "Loading..."
},
"footer": {
"version": "Version",
"commit": "Commit",
"build": "Build",
"version_unknown": "Unknown"
},
"credentials": {
"description": "Manage OAuth and token-based credentials for supported providers.",
"loading": "Loading credentials...",
+6
View File
@@ -93,6 +93,12 @@
"labels": {
"loading": "加载中..."
},
"footer": {
"version": "版本",
"commit": "提交",
"build": "构建",
"version_unknown": "未知"
},
"credentials": {
"description": "管理已支持服务商的 OAuth 与 Token 凭据。",
"loading": "正在加载凭据...",