refactor(housekeeping): split client, add loading states, URL persistence, fix dead code
Local Build and Deploy / deploy (push) Failing after 48s

- Split ManageClient into ManageSection, PresetsSection, TestSection,
  ImportSection, ExportSection - each tab only renders what it needs
- Add loading/disabled states to preset, import, export, clear buttons
- Persist search and group filter via URL searchParams (survives refresh)
- Remove dead getAuditHistory export from actions
- Fix testRankPermission - remove unnecessary revalidatePath with JSON result
- Clean up unused errors/count variables in bulkImportPermissions
- Add 'loading' translation key to housekeeping section (en/nl)
This commit is contained in:
openhands committed 2026-07-17 19:28:19 +02:00
1 parent 0a350a354e
commit 70f5e37373
7 files changed
+199 -189

No files matched your search

Binary file not shown.
Binary file not shown.
+2 -17
View File
@@ -131,9 +131,6 @@ export async function bulkImportPermissions(formData: FormData): Promise<void> {
await requirePermission(PERMS.SETTINGS_EDIT); await requirePermission(PERMS.SETTINGS_EDIT);
const raw = sanitize(String(formData.get("json") ?? "")); const raw = sanitize(String(formData.get("json") ?? ""));
const errors: string[] = [];
let count = 0;
if (!raw) return; if (!raw) return;
let parsed: unknown; let parsed: unknown;
@@ -157,7 +154,6 @@ export async function bulkImportPermissions(formData: FormData): Promise<void> {
const dependsOn = sanitize(String(item.dependsOn ?? "")) || null; const dependsOn = sanitize(String(item.dependsOn ?? "")) || null;
if (!permission || !Number.isFinite(minRank) || minRank < 0) { if (!permission || !Number.isFinite(minRank) || minRank < 0) {
errors.push("Invalid entry: " + JSON.stringify(item));
continue; continue;
} }
@@ -180,9 +176,8 @@ export async function bulkImportPermissions(formData: FormData): Promise<void> {
updatedBy: userId ?? undefined, updatedBy: userId ?? undefined,
}, },
}); });
count++;
} catch { } catch {
errors.push("Failed to upsert: " + permission); // Failed to upsert
} }
} }
@@ -881,17 +876,7 @@ export async function testRankPermission(formData: FormData): Promise<void> {
}); });
const granted = perms.map((p) => p.permission); const granted = perms.map((p) => p.permission);
// Result is displayed via the revalidated page revalidatePath("/admin/housekeeping");
revalidatePath(
"/admin/housekeeping?tab=test&result=" +
encodeURIComponent(JSON.stringify({ rank, permissions: granted })),
);
} }
export async function getAuditHistory(): Promise<unknown[]> {
await requirePermission(PERMS.SETTINGS_VIEW);
const { getAuditLogs } = await import("@/lib/services/audit");
const result = await getAuditLogs({ search: "housekeeping", perPage: 50 });
return result.rows;
}
File diff suppressed because it is too large. Load diff
+20 -48
View File
@@ -3,35 +3,21 @@ import { redirect } from "next/navigation";
import { getTranslations } from "next-intl/server"; import { getTranslations } from "next-intl/server";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions"; import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma"; import { prisma } from "@/lib/prisma";
import { ManageClient } from "./client"; import {
ExportSection,
ImportSection,
ManageSection,
PresetsSection,
TestSection,
} from "./client";
export const dynamic = "force-dynamic"; export const dynamic = "force-dynamic";
const GROUPS = [ const GROUPS = [
"Core", "Core", "Users", "Rooms", "Bans", "News", "Logs", "Settings",
"Users", "Wordfilter", "Catalog", "Shop", "Events", "Tickets", "Moderation",
"Rooms", "Polls", "Analytics", "DevOps", "Prefixes", "Banners", "Radio",
"Bans", "RCON", "Assets", "Export", "Notifications", "CMS Pages",
"News",
"Logs",
"Settings",
"Wordfilter",
"Catalog",
"Shop",
"Events",
"Tickets",
"Moderation",
"Polls",
"Analytics",
"DevOps",
"Prefixes",
"Banners",
"Radio",
"RCON",
"Assets",
"Export",
"Notifications",
"CMS Pages",
]; ];
export default async function AdminHousekeeping({ export default async function AdminHousekeeping({
@@ -241,7 +227,7 @@ export default async function AdminHousekeeping({
)} )}
{tab === "manage" && ( {tab === "manage" && (
<ManageClient <ManageSection
permissions={allPermissions} permissions={allPermissions}
groups={allGroups} groups={allGroups}
groupCounts={groupCounts} groupCounts={groupCounts}
@@ -250,31 +236,17 @@ export default async function AdminHousekeeping({
)} )}
{tab === "import" && ( {tab === "import" && (
<ManageClient <>
permissions={allPermissions} <ImportSection />
groups={allGroups} <div className="mt-8">
groupCounts={groupCounts} <ExportSection />
permSet={permSet} </div>
/> </>
)} )}
{tab === "presets" && ( {tab === "presets" && <PresetsSection />}
<ManageClient
permissions={allPermissions}
groups={allGroups}
groupCounts={groupCounts}
permSet={permSet}
/>
)}
{tab === "test" && ( {tab === "test" && <TestSection permissions={allPermissions} />}
<ManageClient
permissions={allPermissions}
groups={allGroups}
groupCounts={groupCounts}
permSet={permSet}
/>
)}
{tab === "ranks" && ( {tab === "ranks" && (
<section> <section>
+1
View File
@@ -1881,6 +1881,7 @@
"invalidRank": "Invalid rank", "invalidRank": "Invalid rank",
"testDone": "Test done: {count} permissions found", "testDone": "Test done: {count} permissions found",
"testing": "Testing...", "testing": "Testing...",
"loading": "Loading...",
"prev": "Previous", "prev": "Previous",
"next": "Next", "next": "Next",
"form": { "form": {
+1
View File
@@ -1881,6 +1881,7 @@
"invalidRank": "Ongeldige rang", "invalidRank": "Ongeldige rang",
"testDone": "Test voltooid: {count} permissies gevonden", "testDone": "Test voltooid: {count} permissies gevonden",
"testing": "Testen...", "testing": "Testen...",
"loading": "Laden...",
"prev": "Vorige", "prev": "Vorige",
"next": "Volgende", "next": "Volgende",
"form": { "form": {