2026-03-18 23:08:53 +01:00
|
|
|
import { useState, useMemo } from 'react'
|
|
|
|
|
import { AdminLayout } from '../Admin'
|
|
|
|
|
import { Badge } from '../../../design-system/primitives/Badge/Badge'
|
|
|
|
|
import { DateRangePicker } from '../../../design-system/primitives/DateRangePicker/DateRangePicker'
|
|
|
|
|
import { Input } from '../../../design-system/primitives/Input/Input'
|
|
|
|
|
import { Select } from '../../../design-system/primitives/Select/Select'
|
|
|
|
|
import { MonoText } from '../../../design-system/primitives/MonoText/MonoText'
|
|
|
|
|
import { CodeBlock } from '../../../design-system/primitives/CodeBlock/CodeBlock'
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
import { DataTable } from '../../../design-system/composites/DataTable/DataTable'
|
|
|
|
|
import type { Column } from '../../../design-system/composites/DataTable/types'
|
2026-03-18 23:08:53 +01:00
|
|
|
import type { DateRange } from '../../../design-system/utils/timePresets'
|
|
|
|
|
import { AUDIT_EVENTS, type AuditEvent } from './auditMocks'
|
|
|
|
|
import styles from './AuditLog.module.css'
|
|
|
|
|
|
|
|
|
|
const CATEGORIES = [
|
|
|
|
|
{ value: '', label: 'All categories' },
|
|
|
|
|
{ value: 'INFRA', label: 'INFRA' },
|
|
|
|
|
{ value: 'AUTH', label: 'AUTH' },
|
|
|
|
|
{ value: 'USER_MGMT', label: 'USER_MGMT' },
|
|
|
|
|
{ value: 'CONFIG', label: 'CONFIG' },
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
function formatTimestamp(iso: string): string {
|
|
|
|
|
return new Date(iso).toLocaleString('en-GB', {
|
|
|
|
|
year: 'numeric', month: '2-digit', day: '2-digit',
|
|
|
|
|
hour: '2-digit', minute: '2-digit', second: '2-digit',
|
|
|
|
|
hour12: false,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
const COLUMNS: Column<AuditEvent>[] = [
|
|
|
|
|
{
|
|
|
|
|
key: 'timestamp', header: 'Timestamp', width: '170px', sortable: true,
|
|
|
|
|
render: (_, row) => <MonoText size="xs">{formatTimestamp(row.timestamp)}</MonoText>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'username', header: 'User', sortable: true,
|
|
|
|
|
render: (_, row) => <span style={{ fontWeight: 500 }}>{row.username}</span>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'category', header: 'Category', width: '110px', sortable: true,
|
|
|
|
|
render: (_, row) => <Badge label={row.category} color="auto" />,
|
|
|
|
|
},
|
|
|
|
|
{ key: 'action', header: 'Action' },
|
|
|
|
|
{
|
|
|
|
|
key: 'target', header: 'Target',
|
|
|
|
|
render: (_, row) => <span className={styles.target}>{row.target}</span>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 'result', header: 'Result', width: '90px', sortable: true,
|
|
|
|
|
render: (_, row) => (
|
|
|
|
|
<Badge label={row.result} color={row.result === 'SUCCESS' ? 'success' : 'error'} />
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
2026-03-18 23:08:53 +01:00
|
|
|
const now = Date.now()
|
|
|
|
|
const INITIAL_RANGE: DateRange = {
|
|
|
|
|
from: new Date(now - 7 * 24 * 3600_000).toISOString().slice(0, 16),
|
|
|
|
|
to: new Date(now).toISOString().slice(0, 16),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function AuditLog() {
|
|
|
|
|
const [dateRange, setDateRange] = useState<DateRange>(INITIAL_RANGE)
|
|
|
|
|
const [userFilter, setUserFilter] = useState('')
|
|
|
|
|
const [categoryFilter, setCategoryFilter] = useState('')
|
|
|
|
|
const [searchFilter, setSearchFilter] = useState('')
|
|
|
|
|
|
|
|
|
|
const filtered = useMemo(() => {
|
|
|
|
|
const from = new Date(dateRange.from).getTime()
|
|
|
|
|
const to = new Date(dateRange.to).getTime()
|
|
|
|
|
return AUDIT_EVENTS.filter((e) => {
|
|
|
|
|
const ts = new Date(e.timestamp).getTime()
|
|
|
|
|
if (ts < from || ts > to) return false
|
|
|
|
|
if (userFilter && !e.username.toLowerCase().includes(userFilter.toLowerCase())) return false
|
|
|
|
|
if (categoryFilter && e.category !== categoryFilter) return false
|
|
|
|
|
if (searchFilter) {
|
|
|
|
|
const q = searchFilter.toLowerCase()
|
|
|
|
|
if (!e.action.toLowerCase().includes(q) && !e.target.toLowerCase().includes(q)) return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
})
|
|
|
|
|
}, [dateRange, userFilter, categoryFilter, searchFilter])
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<AdminLayout title="Audit Log">
|
|
|
|
|
<div className={styles.filters}>
|
|
|
|
|
<DateRangePicker
|
|
|
|
|
value={dateRange}
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
onChange={setDateRange}
|
2026-03-18 23:08:53 +01:00
|
|
|
/>
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="Filter by user..."
|
|
|
|
|
value={userFilter}
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
onChange={(e) => setUserFilter(e.target.value)}
|
|
|
|
|
onClear={() => setUserFilter('')}
|
2026-03-18 23:08:53 +01:00
|
|
|
className={styles.filterInput}
|
|
|
|
|
/>
|
|
|
|
|
<Select
|
|
|
|
|
options={CATEGORIES}
|
|
|
|
|
value={categoryFilter}
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
onChange={(e) => setCategoryFilter(e.target.value)}
|
2026-03-18 23:08:53 +01:00
|
|
|
className={styles.filterSelect}
|
|
|
|
|
/>
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="Search action or target..."
|
|
|
|
|
value={searchFilter}
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
onChange={(e) => setSearchFilter(e.target.value)}
|
|
|
|
|
onClear={() => setSearchFilter('')}
|
2026-03-18 23:08:53 +01:00
|
|
|
className={styles.filterInput}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
<div className={styles.tableSection}>
|
|
|
|
|
<div className={styles.tableHeader}>
|
|
|
|
|
<span className={styles.tableTitle}>Audit Log</span>
|
|
|
|
|
<div className={styles.tableRight}>
|
|
|
|
|
<span className={styles.tableMeta}>
|
|
|
|
|
{filtered.length} events
|
|
|
|
|
</span>
|
|
|
|
|
<Badge label="LIVE" color="success" />
|
|
|
|
|
</div>
|
2026-03-18 23:08:53 +01:00
|
|
|
</div>
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
<DataTable
|
|
|
|
|
columns={COLUMNS}
|
|
|
|
|
data={filtered}
|
|
|
|
|
sortable
|
|
|
|
|
flush
|
|
|
|
|
pageSize={10}
|
|
|
|
|
rowAccent={(row) => row.result === 'FAILURE' ? 'error' : undefined}
|
|
|
|
|
expandedContent={(row) => (
|
|
|
|
|
<div className={styles.expandedDetail}>
|
|
|
|
|
<div className={styles.detailGrid}>
|
|
|
|
|
<div className={styles.detailField}>
|
|
|
|
|
<span className={styles.detailLabel}>IP Address</span>
|
|
|
|
|
<MonoText size="xs">{row.ipAddress}</MonoText>
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.detailField}>
|
|
|
|
|
<span className={styles.detailLabel}>User Agent</span>
|
|
|
|
|
<span className={styles.detailValue}>{row.userAgent}</span>
|
|
|
|
|
</div>
|
2026-03-18 23:08:53 +01:00
|
|
|
</div>
|
|
|
|
|
<div className={styles.detailField}>
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
<span className={styles.detailLabel}>Detail</span>
|
|
|
|
|
<CodeBlock content={JSON.stringify(row.detail, null, 2)} language="json" />
|
2026-03-18 23:08:53 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
refactor: admin section UX/UI redesign
- Fix critical --bg-base token bug (dark mode broken), replace with --bg-surface
- Replace hand-rolled admin nav with Tabs composite (proper ARIA)
- Migrate AuditLog from custom table to DataTable with sorting, row accents, card wrapper
- Remove duplicate h2 page titles (breadcrumb + tab already identify the page)
- Rework user creation with provider-aware form (Local/OIDC RadioGroup)
- Add Security section with password reset for local users, OIDC info for external
- Add toast notifications to all RBAC mutations (create/delete/add/remove)
- Add confirmation dialogs for cascading removals (group/role)
- Add keyboard accessibility to entity lists (role/tabIndex/aria-selected)
- Add empty search states, duplicate name validation
- Replace lock emoji with Badge, fix radii/shadow/padding consistency
- Badge dashed variant keeps background color
- Inherited roles shown with dashed outline + reduced opacity
- Inline MultiSelect (+Add) for groups, roles, members, child groups
- Center OIDC form, replace inline styles with CSS modules
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:44:19 +01:00
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</AdminLayout>
|
2026-03-18 23:08:53 +01:00
|
|
|
)
|
|
|
|
|
}
|