From b6357ad68bd41f20cba07b48faffb46f157f0745 Mon Sep 17 00:00:00 2001 From: Lemon-miaow Date: Sun, 27 Sep 2026 15:23:48 +0800 Subject: [PATCH] =?UTF-8?q?fix(panel):=20=E5=8F=AF=E8=AE=A4=E9=A2=86?= =?UTF-8?q?=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8=E8=A1=8C=E5=8E=BB=E6=8E=89?= =?UTF-8?q?=E7=82=B9=E4=B8=8D=E4=BA=86=E7=9A=84=E6=8E=A7=E5=88=B6=E5=8F=B0?= =?UTF-8?q?=E6=8C=89=E9=92=AE=EF=BC=8C=E7=AE=A1=E7=90=86=E5=91=98=E5=9C=A8?= =?UTF-8?q?=E8=AE=A4=E9=A2=86=E6=97=81=E4=BF=9D=E7=95=99=E5=94=A4=E9=86=92?= =?UTF-8?q?=E5=92=8C=E6=8E=A7=E5=88=B6=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- panel/src/pages/servers/ServersPage.test.tsx | 30 ++++++++++++ panel/src/pages/servers/ServersPage.tsx | 49 ++++++++++---------- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/panel/src/pages/servers/ServersPage.test.tsx b/panel/src/pages/servers/ServersPage.test.tsx index 51c1eba..37b6dd0 100644 --- a/panel/src/pages/servers/ServersPage.test.tsx +++ b/panel/src/pages/servers/ServersPage.test.tsx @@ -111,6 +111,36 @@ describe("ServersPage fleet ownership", () => { expect(skyblock.getByRole("button", { name: /Claim/ })).toBeTruthy(); }); + it("offers a player only the claim on a server nobody owns, and an admin its wake and console too", async () => { + tier.isAdmin = false; + calls.myServers.mockResolvedValue([ + { name: "skyblock", subdomain: "skyblock", owned: false, claimable: true, phase: "Stopped", playersOnline: 0, playersMax: 20 }, + ] satisfies MyServerView[]); + const { unmount } = render( + + + , + ); + let skyblock = await tableRow("skyblock"); + const names = skyblock.getAllByRole("button").map((b) => b.getAttribute("aria-label") ?? b.textContent?.trim()); + expect(names).toEqual(["Copy address skyblock.example.test:25570", "Claim"]); + expect(skyblock.queryByRole("link")).toBeNull(); + unmount(); + + tier.isAdmin = true; + calls.fleet.mockResolvedValue([row("skyblock", { claimable: true })]); + render( + + + , + ); + skyblock = await tableRow("skyblock"); + expect(skyblock.getByRole("button", { name: /Claim/ })).toBeTruthy(); + expect(skyblock.getByRole("button", { name: /Wake/ })).toHaveProperty("disabled", false); + expect(skyblock.getByRole("link").getAttribute("href")).toBe("/servers/skyblock"); + expect(within(skyblock.getByRole("link")).getByRole("button", { name: /Console/ })).toHaveProperty("disabled", false); + }); + it("says the owner is unknown and offers no claim when the lookup failed", async () => { calls.fleet.mockResolvedValue([row("survival", { ownerUnknown: true })]); render( diff --git a/panel/src/pages/servers/ServersPage.tsx b/panel/src/pages/servers/ServersPage.tsx index fe990ae..a5a7aae 100644 --- a/panel/src/pages/servers/ServersPage.tsx +++ b/panel/src/pages/servers/ServersPage.tsx @@ -525,10 +525,15 @@ function ServerActions({ ); } + // An unclaimed server is the player's to claim and nothing more: waking it and + // its console belong to its owner, and it has none yet. An admin runs any server + // (the wake and console routes admit them), so theirs keep both beside the claim. + const claimable = server.claimable && !server.owned; + return (
- {server.claimable && !server.owned ? ( + {claimable && ( <> - @@ -566,26 +568,25 @@ function ServerActions({ - ) : ( - <> - - {(server.owned || isAdmin) && ( - - - - )} - + )} + {(!claimable || isAdmin) && ( + + )} + {(server.owned || isAdmin) && ( + + + )}
{error && (