1
0
forked from baron/baron-sso

Consent 목록 CSV 내보내기 구현

This commit is contained in:
2026-02-26 13:58:20 +09:00
parent 5a7231eba6
commit 39062e1773

View File

@@ -80,6 +80,56 @@ function ClientConsentsPage() {
return scopeFilter === "all" || row.grantedScopes.includes(scopeFilter);
});
const handleExportCSV = () => {
if (filteredRows.length === 0) return;
const headers = [
t("ui.dev.clients.consents.table.user", "User"),
t("ui.dev.clients.consents.table.tenant", "Tenant"),
t("ui.dev.clients.table.status", "Status"),
t("ui.dev.clients.consents.table.scopes", "Granted Scopes"),
t("ui.dev.clients.consents.table.first_granted", "First Granted"),
t(
"ui.dev.clients.consents.table.last_auth",
"Last Authenticated / Revoked",
),
];
const csvContent = [
headers.join(","),
...filteredRows.map((row) => {
const lastAuthRevoked =
row.status === "revoked" && row.deletedAt
? `${t("ui.dev.clients.consents.status_revoked", "Revoked")}: ${new Date(row.deletedAt).toLocaleString()}`
: row.authenticatedAt
? new Date(row.authenticatedAt).toLocaleString()
: "-";
return [
`"${row.subject} (${row.userName || ""})"`,
`"${row.tenantName || row.tenantId || ""}"`,
`"${row.status}"`,
`"${row.grantedScopes.join(", ")}"`,
`"${new Date(row.createdAt).toLocaleString()}"`,
`"${lastAuthRevoked}"`,
].join(",");
}),
].join("\n");
const blob = new Blob(["\uFEFF" + csvContent], {
type: "text/csv;charset=utf-8;",
});
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
const date = new Date().toISOString().split("T")[0];
link.setAttribute("href", url);
link.setAttribute("download", `consents_${clientId}_${date}.csv`);
link.style.visibility = "hidden";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
return (
<div className="space-y-8">
<header className="space-y-4">
@@ -191,7 +241,11 @@ function ClientConsentsPage() {
>
{t("ui.common.search", "검색")}
</Button>
<Button className="shadow-sm shadow-primary/30">
<Button
className="shadow-sm shadow-primary/30"
onClick={handleExportCSV}
disabled={filteredRows.length === 0}
>
{t("ui.dev.clients.consents.export_csv", "Export CSV")}
</Button>
</div>
@@ -455,6 +509,8 @@ function ClientConsentsPage() {
{rows.reduce((acc, row) => acc + row.grantedScopes.length, 0)}
</CardTitle>
</CardHeader>
</Card>
<Card className="glass-panel">
<CardHeader className="pb-2">
<p className="text-xs font-bold uppercase tracking-wider text-muted-foreground">
{t(