fix(panel): 服务器列表无匹配时给出真的清除筛选按钮,清掉搜索和状态筛选并回到第一页
This commit is contained in:
2 files changed
+73
-4
No files matched your search
@@ -1,6 +1,6 @@
|
||||
// @vitest-environment jsdom
|
||||
import { describe, it, expect, vi, beforeEach, beforeAll } from "vitest";
|
||||
import { render, screen, within } from "@testing-library/react";
|
||||
import { describe, it, expect, vi, beforeEach, beforeAll, afterEach } from "vitest";
|
||||
import { act, render, screen, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { MemoryRouter } from "react-router-dom";
|
||||
import type { FleetServer, MyServerView } from "@/lib/types";
|
||||
@@ -341,3 +341,60 @@ describe("ServersPage order and paging", () => {
|
||||
expect(await tableOrder()).toEqual(names.slice(0, 20));
|
||||
});
|
||||
});
|
||||
|
||||
describe("ServersPage with nothing matching", () => {
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("clears the search and the phase filter from the empty state", async () => {
|
||||
tier.isAdmin = false;
|
||||
const mine = (name: string): MyServerView => ({
|
||||
name,
|
||||
subdomain: name,
|
||||
owned: true,
|
||||
claimable: false,
|
||||
phase: "Running",
|
||||
playersOnline: 0,
|
||||
playersMax: 20,
|
||||
});
|
||||
calls.myServers.mockResolvedValue([mine("survival"), mine("creative")]);
|
||||
const user = renderPage();
|
||||
await tableOrder();
|
||||
|
||||
const search = screen.getByPlaceholderText(/Search/) as HTMLInputElement;
|
||||
await user.type(search, "zzz");
|
||||
await user.click(screen.getByRole("combobox", { name: "Filter by phase" }));
|
||||
await user.click(await screen.findByRole("option", { name: "Stopping" }));
|
||||
expect(screen.getByText("No matching servers found.")).toBeTruthy();
|
||||
expect(screen.getByText("No server matches the current search or filter.")).toBeTruthy();
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Clear filters" }));
|
||||
expect(await tableOrder()).toEqual(["creative", "survival"]);
|
||||
expect(search.value).toBe("");
|
||||
expect(screen.getByRole("combobox", { name: "Filter by phase" }).textContent).toBe("All phases");
|
||||
});
|
||||
|
||||
it("starts the cleared list from its first page", async () => {
|
||||
vi.useFakeTimers({ shouldAdvanceTime: true });
|
||||
const names = Array.from({ length: 21 }, (_, i) => `srv-${String(i + 1).padStart(2, "0")}`);
|
||||
calls.fleet.mockResolvedValue(names.map((n) => row(n, { phase: "Running", ready: true })));
|
||||
const user = userEvent.setup({ advanceTimers: vi.advanceTimersByTime });
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<ServersPage />
|
||||
</MemoryRouter>,
|
||||
);
|
||||
await tableOrder();
|
||||
await user.click(screen.getByRole("combobox", { name: "Filter by phase" }));
|
||||
await user.click(await screen.findByRole("option", { name: "Running" }));
|
||||
await user.click(screen.getByRole("button", { name: /Next/ }));
|
||||
expect(await tableOrder()).toEqual(["srv-21"]);
|
||||
|
||||
// The next reread finds every server stopped, so the filtered page empties.
|
||||
calls.fleet.mockResolvedValue(names.map((n) => row(n, {})));
|
||||
await act(() => vi.advanceTimersByTimeAsync(10_000));
|
||||
await user.click(await screen.findByRole("button", { name: "Clear filters" }));
|
||||
expect(await tableOrder()).toEqual(names.slice(0, 20));
|
||||
});
|
||||
});
|
||||
@@ -402,8 +402,20 @@ export function ServersPage() {
|
||||
) : visible.length === 0 ? (
|
||||
<EmptyState
|
||||
title={isAdmin ? t("fleet_no_match_title") : t("servers:search_no_match")}
|
||||
hint={isAdmin ? t("fleet_no_match_hint") : t("servers:search_clear_btn")}
|
||||
/>
|
||||
hint={t("fleet_no_match_hint")}
|
||||
>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setQuery("");
|
||||
setPhaseFilter("all");
|
||||
setPage(1);
|
||||
}}
|
||||
>
|
||||
{t("servers:search_clear_btn")}
|
||||
</Button>
|
||||
</EmptyState>
|
||||
) : (
|
||||
<>
|
||||
{/* Cards until the table fits (two per row from md). The admin
|
||||
|
||||
Reference in new issue
Block a user