forked from baron/baron-sso
perf(admin): full-stack performance optimization for all list tables
- Implemented server-side search, infinite scrolling, and list virtualization for Tenants, Users, and Audit Logs. - Backend: Enhanced Repository, Service, and Handler layers to support 'search' and 'cursor' parameters. - Frontend: Integrated @tanstack/react-virtual and useInfiniteQuery for high-performance rendering. - Quality: Updated all unit tests and E2E tests to match the new asynchronous server-side search architecture. - i18n: Synced all translation keys and cleaned up unused resources.
This commit is contained in:
@@ -53,13 +53,33 @@ test.describe("Audit Logs Management", () => {
|
||||
const url = route.request().url();
|
||||
const urlObj = new URL(url);
|
||||
const cursor = urlObj.searchParams.get("cursor");
|
||||
const search = urlObj.searchParams.get("search")?.toLowerCase();
|
||||
const status = urlObj.searchParams.get("status");
|
||||
const offset = cursor ? 20 : 0;
|
||||
console.log(`[mock] Audit logs request: ${url} (offset: ${offset})`);
|
||||
|
||||
let allMockLogs = generateMockLogs(40, 0);
|
||||
if (status && status !== "all") {
|
||||
allMockLogs = allMockLogs.filter((l) => l.status === status);
|
||||
}
|
||||
if (search) {
|
||||
allMockLogs = allMockLogs.filter(
|
||||
(l) =>
|
||||
l.user_id.toLowerCase().includes(search) ||
|
||||
l.details.toLowerCase().includes(search),
|
||||
);
|
||||
}
|
||||
|
||||
const paginatedItems = allMockLogs.slice(offset, offset + 20);
|
||||
|
||||
console.log(
|
||||
`[mock] Audit logs request: ${url} (offset: ${offset}, search: ${search}, status: ${status}, results: ${paginatedItems.length})`,
|
||||
);
|
||||
|
||||
return route.fulfill({
|
||||
json: {
|
||||
items: generateMockLogs(20, offset),
|
||||
next_cursor: offset === 0 ? "fake-cursor" : null,
|
||||
total: 40,
|
||||
items: paginatedItems,
|
||||
next_cursor: allMockLogs.length > offset + 20 ? "fake-cursor" : null,
|
||||
total: allMockLogs.length,
|
||||
},
|
||||
headers: { "Access-Control-Allow-Origin": "*" },
|
||||
});
|
||||
@@ -172,7 +192,7 @@ test.describe("Audit Logs Management", () => {
|
||||
await userIdInput.fill("user-even");
|
||||
|
||||
// Wait for deferred value to apply
|
||||
await expect(page.locator("tbody tr")).toHaveCount(10, { timeout: 15000 });
|
||||
await expect(page.locator("tbody tr")).toHaveCount(20, { timeout: 15000 });
|
||||
await expect(page.locator("tbody")).not.toContainText("user-odd");
|
||||
|
||||
// Clear User ID
|
||||
@@ -183,12 +203,13 @@ test.describe("Audit Logs Management", () => {
|
||||
const actionInput = page.getByTestId("audit-search-action");
|
||||
await actionInput.fill("ROTATE_SECRET");
|
||||
|
||||
// Check that we only see ROTATE_SECRET (20 - 7 = 13)
|
||||
await expect(page.locator("tbody tr")).toHaveCount(13, { timeout: 15000 });
|
||||
// Check that we see ROTATE_SECRET across all 40 logs (40 - 14 = 26)
|
||||
// Wait for the mock to respond and render
|
||||
await expect(page.locator("tbody tr")).toHaveCount(20, { timeout: 15000 });
|
||||
await expect(page.locator("tbody")).not.toContainText("CREATE_TENANT");
|
||||
});
|
||||
|
||||
test("should filter logs by Status locally", async ({ page }) => {
|
||||
test("should filter logs by Status", async ({ page }) => {
|
||||
await page.goto("/audit-logs");
|
||||
await expect(page.locator(".animate-spin")).not.toBeVisible({
|
||||
timeout: 10000,
|
||||
@@ -201,12 +222,13 @@ test.describe("Audit Logs Management", () => {
|
||||
// Select "Failure" status
|
||||
await page.getByTestId("audit-filter-status").selectOption("failure");
|
||||
|
||||
// ID % 5 === 0 are status "failure" (0, 5, 10, 15)
|
||||
await expect(page.locator("tbody tr")).toHaveCount(4, { timeout: 15000 });
|
||||
// Total 8 failures in 40 logs
|
||||
await expect(page.locator("tbody tr")).toHaveCount(8, { timeout: 15000 });
|
||||
|
||||
// Select "Success" status
|
||||
await page.getByTestId("audit-filter-status").selectOption("success");
|
||||
|
||||
await expect(page.locator("tbody tr")).toHaveCount(16, { timeout: 15000 });
|
||||
// Total 32 successes in 40 logs, but page limit is 20
|
||||
await expect(page.locator("tbody tr")).toHaveCount(20, { timeout: 15000 });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user