diff --git a/web/src/NetworkExitsPage.jsx b/web/src/NetworkExitsPage.jsx index aecb2b6..729a96b 100644 --- a/web/src/NetworkExitsPage.jsx +++ b/web/src/NetworkExitsPage.jsx @@ -244,16 +244,18 @@ function ExitTable({ exits, accountsByExit, bindingsError, busy, onAction }) { const columns = [ { header: "出口", - width: "20%", + width: "22%", render: (exit) => (
- {exit.protocol}://{exit.host}:{exit.port} + {exit.id} -

{exit.id}

+

+ {exit.protocol}://{exit.host}:{exit.port} +

), }, @@ -264,14 +266,14 @@ function ExitTable({ exits, accountsByExit, bindingsError, busy, onAction }) { }, { header: "用户名", - width: "11%", + width: "10%", render: (exit) => ( {exit.username || "无"} ), }, { header: "密码", - width: "11%", + width: "10%", render: (exit) => ( {exit.password || "无"} ), @@ -280,7 +282,9 @@ function ExitTable({ exits, accountsByExit, bindingsError, busy, onAction }) { header: "出口IP", width: "13%", render: (exit) => ( - {exit.observed_public_ip || "尚无观测"} + + {exit.observed_public_ip || "尚无观测"} + ), }, { @@ -309,11 +313,7 @@ function ExitTable({ exits, accountsByExit, bindingsError, busy, onAction }) { width: "8%", align: "right", render: (exit) => ( - + ), }, ]; diff --git a/web/src/NetworkExitsPage.test.jsx b/web/src/NetworkExitsPage.test.jsx index 919d535..102892c 100644 --- a/web/src/NetworkExitsPage.test.jsx +++ b/web/src/NetworkExitsPage.test.jsx @@ -74,10 +74,13 @@ describe("NetworkExitList", () => { expect(await screen.findByText(/创建并检测健康后/)).toBeTruthy(); }); - it("shows stored credentials and runs an explicit health check", async () => { + it("shows the exit ID as the primary identifier with stored credentials", async () => { const dataProvider = provider([networkExit]); renderExits(dataProvider); + const idLink = await screen.findByRole("link", { name: "exit-a" }); + expect(idLink.getAttribute("href")).toBe("/network-exits/exit-a"); + expect(screen.getByText("socks5://proxy.example:1080")).toBeTruthy(); expect((await screen.findAllByText(/proxy-user/)).length).toBeGreaterThan( 0, );