feat(hk): expand search and add operational user overview
This commit is contained in:
1 parent
27447ce029
commit
89526af344
44 files changed
+3740
-416
No files matched your search
@@ -54,6 +54,9 @@ vi.mock("@/lib/db", () => {
|
||||
where() {
|
||||
return query;
|
||||
},
|
||||
orderBy() {
|
||||
return query;
|
||||
},
|
||||
async limit() {
|
||||
state.queried.push(table);
|
||||
return [{ id: 1, title: "Match", subtitle: "Data" }];
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { AdminSearchRequest } from "./admin-search-request";
|
||||
|
||||
describe("admin search request ownership", () => {
|
||||
it("rejects a late response after the input changes, even before the next debounce fires", async () => {
|
||||
const requests = new AdminSearchRequest();
|
||||
const first = requests.start();
|
||||
const late = Promise.resolve().then(() => requests.accepts(first));
|
||||
requests.cancel();
|
||||
expect(await late).toBe(false);
|
||||
expect(first.signal.aborted).toBe(true);
|
||||
});
|
||||
it("accepts only the newest request and rejects completion after closing", () => {
|
||||
const requests = new AdminSearchRequest();
|
||||
const first = requests.start();
|
||||
const second = requests.start();
|
||||
expect(requests.accepts(first)).toBe(false);
|
||||
expect(requests.accepts(second)).toBe(true);
|
||||
requests.cancel();
|
||||
expect(requests.accepts(second)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/** Owns the single request allowed to update a search dialog. */
|
||||
export class AdminSearchRequest {
|
||||
private current: AbortController | null = null;
|
||||
|
||||
cancel() {
|
||||
this.current?.abort();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
start() {
|
||||
this.cancel();
|
||||
const controller = new AbortController();
|
||||
this.current = controller;
|
||||
return controller;
|
||||
}
|
||||
|
||||
accepts(controller: AbortController) {
|
||||
return this.current === controller && !controller.signal.aborted;
|
||||
}
|
||||
}
|
||||
@@ -36,16 +36,18 @@ describe("staff smoke contract", () => {
|
||||
expect(detail).toContain("canLiftBan");
|
||||
});
|
||||
|
||||
it("exposes sanction timeline on user show", () => {
|
||||
it("exposes operational overview on user show", () => {
|
||||
expect(
|
||||
existsSync("src/app/admin/users/_components/user-sanction-timeline.tsx"),
|
||||
existsSync(
|
||||
"src/app/admin/users/_components/user-operational-overview.tsx",
|
||||
),
|
||||
).toBe(true);
|
||||
expect(existsSync("src/app/admin/users/_lib/load-user-sanctions.ts")).toBe(
|
||||
expect(existsSync("src/app/admin/users/_lib/load-user-overview.ts")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(
|
||||
readFileSync("src/app/admin/users/show/[id]/page.tsx", "utf8"),
|
||||
).toContain("UserSanctionTimeline");
|
||||
).toContain("UserOperationalOverview");
|
||||
});
|
||||
|
||||
it("applies CMS SQL from drizzle/migrations (not Prisma)", () => {
|
||||
|
||||
Reference in new issue
Block a user