Use friendly UI labels and release feedback (Refs #120)
CI / checks (push) Successful in 6m39s

This commit is contained in:
2026-10-17 09:54:01 -04:00
parent d93a766578
commit 2e6eb0bdb0
8 changed files with 387 additions and 51 deletions
+14 -31
View File
@@ -8,6 +8,7 @@
import { invalidateAll } from '$app/navigation';
import type { AuthUser, UserRole } from '$lib/auth.js';
import { confirmAction } from '$ui/confirm.js';
import { auditPresentation } from '$ui/audit.js';
import Button from '$ui/components/primitives/Button.svelte';
import Dialog from '$ui/components/primitives/Dialog.svelte';
import SectionHeader from '$ui/components/primitives/SectionHeader.svelte';
@@ -101,24 +102,6 @@
auditLoading = false;
}
}
const actionLabels: Record<string, string> = {
setup: 'Administrator created',
login: 'Signed in',
'login.failed': 'Sign-in failed',
logout: 'Signed out',
'sessions.revoked': 'Sessions ended',
'user.created': 'User created',
'user.updated': 'Access updated',
'password.changed': 'Password changed'
};
function auditDetails(value: string): string {
try {
const parsed = JSON.parse(value);
return Object.keys(parsed).length ? JSON.stringify(parsed, null, 2) : '';
} catch {
return value;
}
}
onMount(() => {
if (canViewUsers) void Promise.all([load(), loadAudit()]);
else {
@@ -339,7 +322,7 @@
<div class="audit-heading">
<div>
<h2 id="audit-title">Account activity</h2>
<p class="muted">The latest 200 sign-in and account events.</p>
<p class="muted">The latest 200 sign-in, account, and action events.</p>
</div>
<Button size="sm" variant="ghost" disabled={auditLoading} onclick={loadAudit}
>Refresh activity</Button
@@ -354,27 +337,27 @@
<table>
<thead
><tr
><th>Time</th><th>Event</th><th>By</th><th>Account</th><th
><th>Time</th><th>Event</th><th>By</th><th>Account or action</th><th
>Details</th
></tr
></thead
><tbody>
{#each events as event (event.id)}{@const details = auditDetails(
event.details
)}<tr
{#each events as event (event.id)}{@const presentation =
auditPresentation(event)}<tr
><td class="event-time"
><RelativeTime value={event.createdAt} /></td
><td>{actionLabels[event.action] ?? event.action}</td><td
><td>{presentation.label}</td><td
>{event.actor ? `@${event.actor}` : 'Unauthenticated'}</td
><td
>{event.targetId
? (users.find((user) => user.id === event.targetId)
?.username ?? event.targetId)
: '—'}</td
>{presentation.requestAction ??
(event.targetId
? (users.find((user) => user.id === event.targetId)
?.username ?? event.targetId)
: '—')}</td
><td
>{#if details}<details>
<summary>View details</summary>
<pre>{details}</pre>
>{#if presentation.details}<details>
<summary>Technical details</summary>
<pre>{presentation.details}</pre>
</details>{:else}—{/if}</td
></tr
>{/each}