1
0
forked from baron/baron-sso

감사로그 검색창 통일화

This commit is contained in:
2026-05-14 15:06:34 +09:00
parent faffb6dc05
commit cb602de049

View File

@@ -32,6 +32,7 @@ import {
TableHeader, TableHeader,
TableRow, TableRow,
} from "../../components/ui/table"; } from "../../components/ui/table";
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
import { PageHeader } from "../../../../common/core/components/page"; import { PageHeader } from "../../../../common/core/components/page";
import type { AuditLog } from "../../lib/adminApi"; import type { AuditLog } from "../../lib/adminApi";
import { fetchAuditLogs } from "../../lib/adminApi"; import { fetchAuditLogs } from "../../lib/adminApi";
@@ -205,59 +206,68 @@ function AuditLogsPage() {
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="flex-1 flex flex-col min-h-0 pt-0"> <CardContent className="flex-1 flex flex-col min-h-0 pt-0">
<div className="mb-4 flex flex-wrap items-center gap-2 flex-shrink-0"> <SearchFilterBar
<div className="flex flex-1 items-center gap-2 rounded-full border border-[var(--color-border)] bg-[rgba(255,255,255,0.02)] px-4 py-2 text-[var(--color-muted)]"> className="mb-4"
<Search size={14} /> primary={
<input <div className="flex flex-1 items-center gap-2">
value={filterDraft} <div className="relative flex-1">
onChange={(event) => setFilterDraft(event.target.value)} <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
onKeyDown={(event) => { <input
if (event.key === "Enter") { value={filterDraft}
handleAddFilter(); onChange={(event) => setFilterDraft(event.target.value)}
} onKeyDown={(event) => {
}} if (event.key === "Enter") {
placeholder={t( handleAddFilter();
"ui.admin.audit.filters.placeholder", }
"필터 추가 (예: status:failure)", }}
)} placeholder={t(
className="w-full bg-transparent text-sm text-foreground outline-none" "ui.admin.audit.filters.placeholder",
/> "필터 추가 (예: status:failure)",
<Button size="sm" variant="outline" onClick={handleAddFilter}>
{t("ui.common.add", "추가")}
</Button>
</div>
{filters.length === 0 ? (
<span className="text-xs text-[var(--color-muted)]">
{t("msg.admin.audit.filters.empty", "필터 없음")}
</span>
) : (
filters.map((filter) => (
<span
key={filter}
className="inline-flex items-center gap-2 rounded-full border border-[var(--color-border)] bg-[rgba(255,255,255,0.04)] px-3 py-1 text-xs text-[var(--color-muted)]"
>
<Terminal size={12} />
{filter}
<button
type="button"
onClick={() =>
setFilters((prev) =>
prev.filter((item) => item !== filter),
)
}
className="inline-flex h-5 w-5 items-center justify-center rounded-full border border-[var(--color-border)] text-[10px] text-[var(--color-muted)]"
aria-label={t(
"ui.admin.audit.filters.remove",
"{{filter}} 필터 제거",
{ filter },
)} )}
> className="h-10 w-full rounded-md border border-input bg-background pl-10 pr-3 text-sm outline-none"
× />
</button> </div>
</span> <Button size="sm" variant="outline" onClick={handleAddFilter}>
)) {t("ui.common.add", "추가")}
)} </Button>
</div> </div>
}
actions={
<>
{filters.length === 0 ? (
<span className="text-xs text-[var(--color-muted)]">
{t("msg.admin.audit.filters.empty", "필터 없음")}
</span>
) : (
filters.map((filter) => (
<span
key={filter}
className="inline-flex items-center gap-2 rounded-full border border-[var(--color-border)] bg-[rgba(255,255,255,0.04)] px-3 py-1 text-xs text-[var(--color-muted)]"
>
<Terminal size={12} />
{filter}
<button
type="button"
onClick={() =>
setFilters((prev) =>
prev.filter((item) => item !== filter),
)
}
className="inline-flex h-5 w-5 items-center justify-center rounded-full border border-[var(--color-border)] text-[10px] text-[var(--color-muted)]"
aria-label={t(
"ui.admin.audit.filters.remove",
"{{filter}} 필터 제거",
{ filter },
)}
>
×
</button>
</span>
))
)}
</>
}
/>
<div className={commonTableShellClass}> <div className={commonTableShellClass}>
<div className={commonTableViewportClass}> <div className={commonTableViewportClass}>
<Table className="table-fixed"> <Table className="table-fixed">