Skip to content

feat(audit-log): a consistency pass over the list, filters and entry detail - #2453

Merged
Makisuo merged 33 commits into
mainfrom
audit-log-ui/e-design-pass
Nov 10, 2026
Merged

Makisuo merged 33 commits into
mainfrom
audit-log-ui/e-design-pass

Conversation

@Makisuo

@Makisuo Makisuo commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

A consistency pass over the audit log UI. Stacked on #2433.

After the icon pass the page had every piece, but the pieces did not agree with each other: actors were drawn two ways, each row carried a boxed source badge, the filters used three different text tones, and the entry detail wrapped its "Filter" chips onto lines of their own.

Rows

  • Every actor is one 16px marker and a name: initials for a person, the tinted glyph for an API key, agent or the system (named on hover). Names now start on the same line down the column, and an API key's name no longer truncates behind its badge. A system entry reads "System" where it had no name.
  • The source is a quiet glyph and label instead of an outlined badge on every row. Most rows share one source, and the boxes outweighed the action.
  • The day heading sits exactly above the times.

Filters

  • The date range and the three selects read the same way: muted until set, normal weight. "All time" was bold and "Anyone" was bright while "Any resource" was muted.
  • "All" never has a glyph, in any of the three switches.
  • On a phone the four filters share each row evenly instead of ending wherever their label does.
  • The kind description takes the width between the switch and Reload and shortens (full text on hover) instead of pushing Reload to its own row in Data access.

Entry detail

  • Copy and "filter by this" are two small icon buttons right after the value, as one group that wraps with it. The text chips used to wrap alone onto a second line under some values and not others.
  • The outcome has its own row, with the denial reason beside it, matching the list's Outcome column.
  • A value starts on its label's line. A short value used to centre against a taller neighbour, and a value with a copy button sat 2px below its label.
  • "Link to entry" is a quiet link; it was the only orange thing in the panel.
  • The changes table splits Before and After evenly and breaks long values at word boundaries first ("Checko / ut" on a phone).

Found on the #2424 preview

  • The custom range calendar was clipped to the presets' 192px: Friday, Saturday, the second month and Apply were cut off. The popup now sizes to its content.

  • The filtered empty state named four filters ("this range, person, actor type and outcome") whichever one was set. It now says "Nothing recorded matches these filters."

  • Escape did not close the popover once it showed the calendar: pressing "Custom range…" replaced the pressed preset and focus fell to the page. Focus now moves into the popover, and Escape closes it and returns focus to the button (checked in the lab).

Custom range, before After

Kit: copyButton takes the existing icon-2xs button size. attributeFilterAction loses the icon option #2433 added, since nothing uses it now.

Before / after

Before (#2433) After
Phone, before Phone, after Narrow desktop, after

Verification

  • audit-log.scene.test.ts (26) passes, with two new view tests: an open entry offers its three filter buttons by name, and a row names the kind of actor behind an API key.
  • A review pass found a custom range overflowing its button, the actor mark 4px wider than an avatar, and copy and filter overlapping on touch. All fixed in the second commit.
  • apps/web typechecks; oxlint with the CI config is clean; ui:patterns:check and ui:index:check OK; the ui-kit baseline is unchanged (723).
  • Checked in the lab (/lab/audit-log) at 390, 640, 900, 1024, 1200 and 1280px, in the Changes, Data access, All, filtered, expanded and unknown-lookup states.
  • Not run: a preview deploy. The change is view-only and the lab covers every state.

Stack: #2422 → #2423 → #2424 → #2433 → this

🤖 Generated with Claude Code

…lookup filters

The audit log listed every telemetry read and MCP tool call beside the
changes, so the entries an admin opens the page for were buried. The list
now opens on Changes (data access hidden unless it was denied), with Data
access and All one click away, backed by a new kind param on
GET /v2/audit_log.

Also: resource type, action and affected user filters, a lookup field
that turns a pasted id or action into its filter, chips for filters with
no control of their own, a working Custom range, and a /lab/audit-log
page over fixtures.
…ere it came from

Following a trail meant copying an id and pasting it back as a filter.
Every actor, action, resource, affected user and request in an entry's
detail now has a Filter action that lists every entry with that value.

Also: unnamed actors and membership changes show the member's name, a
new Origin section shows surface, IP, country and request, metadata keys
read as labels, and each entry has a link that opens the log on it
(?entry=alog_...) and scrolls it into view.

inlineCode gains size and tone options; the audit log detail and the
alerts hub empty state move onto them, clearing 6 ui-kit baseline
violations.
The list was one undifferentiated column of relative times. Rows now sit
under Today / Yesterday / date headings counted in the viewer's zone,
a denied entry carries a red left edge, and in the All view allowed
reads, tool calls and SQL runs are muted so changes stand out. The
Source column shows from a narrower width.

dayLabel/dayKey move from the users detail into page/kit/day-label so
both pages share them. The audit log list clears its last 3 ui-kit
baseline violations.
In Data access every row is a read, so muting allowed ones dimmed the
whole list. The tone now depends on the view as well as the entry.
… minute was

The link listed the minute around the entry, newest first, so 50 newer
entries pushed it to page 2 where it never opened. The window now ends
at the entry, which therefore heads the first page, and a later page
holding it reveals it too.
…layout

# Conflicts:
#	apps/web/src/page/settings/audit-log/audit-log.scene.test.ts
The web muted reads with its own copy of the server's access suffixes,
so a new access action would be filtered but not muted. The list and an
isAuditAccessAction helper move to @maple/domain/audit-actions; the
backend re-exports it for existing importers.
… and the outcome

Each row leads its action with a glyph for the verb (created, updated, deleted, rolled, read,
tool call, SQL, API request), and the filters carry the same glyphs as the badges they filter by.
The eyebrow and the Filter action take an icon option.
…verb has a glyph

The resource column shares the row's spare width with the action instead of holding a fixed 14rem,
so the label no longer collapses where the column appears. The verb table is total, so a new verb
fails the build until it has a glyph. One actor badge and one denied badge for the rows and the
detail, and an eyebrow with an icon stays block-level on a heading.
…filters

# Conflicts:
#	apps/web/src/route/search.ts
The Origin section was skipped when an entry had no IP, country or request id, which also hid the
surface it always has. Adds a test for that, and one for the window an entry's link opens.
…detail

Rows: every actor is a 16px marker and a name, so names line up; the source is quiet text
instead of a box on each row. Filters read muted until set. Entry detail: copy and filter sit
beside the value as one group, the outcome has its own row, and values start on their label's line.
@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 33 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4e97d8b5-ca0a-41b1-86ab-7ef31b76c81d
Commits

Reviewing files that changed from the base of the PR and between 130c677 and c358bbb.

Files selected for processing: 8

  • apps/web/src/lab/audit-log-lab.ts
  • apps/web/src/page/settings/audit-log/audit-log.scene.test.ts
  • apps/web/src/page/settings/audit-log/model.ts
  • apps/web/src/page/settings/audit-log/update.ts
  • apps/web/src/page/settings/audit-log/view-detail.ts
  • apps/web/src/page/settings/audit-log/view.ts
  • packages/views/src/ui/attributes/attribute-row.ts
  • packages/views/src/ui/copy-button.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@maple-review-bot

This comment has been minimized.

A custom range no longer overflows its button, the actor mark is exactly an avatar wide, copy
and filter keep apart on touch, and the kind description shortens instead of moving Reload.
Adds view tests for the entry's filter buttons and the actor mark's name.
@maple-review-bot

This comment has been minimized.

…e-minute window

An entry link lists the minute ending at its entry. A pivot kept that custom range, so "every
entry with this actor" listed only that minute.
… presets' width

The popover's positioner keeps the width it measured for the presets, and an auto-width popup
stayed inside it: two days of the week, the second month and Apply were cut off. Found on the
preview. Also words the filtered empty state for any filter, not four of them.
Pressing "Custom range" replaced the pressed preset with the calendar and focus fell to the
page, so Escape reached nothing. Focus now moves into the popover. Found on the preview.
@maple-review-bot

This comment has been minimized.

Base automatically changed from audit-log-ui/d-icons to main November 10, 2026 11:19
@maple-review-bot

maple-review-bot Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 10/10 · safe to merge. View-only change on top of an already-reviewed head; every kit option it uses resolves, and the tone/baseline claims are the one part no test can pin.
no findings · tests covered · risk low

A consistency pass over the audit log page: one actor marker per row, quieter source and filters, and a rebuilt entry detail (actions beside values, its own Outcome row). Contained to views and the kit, and safe to merge.

  • actorCell draws one 16px marker for every actor via the new actorMark, hidden from AT when the type is the text beside it
  • identifier in the detail takes an optional pivot action, so copy and Filter wrap as one group
  • ResolvedCustomToday emits FocusAuditDateRange, moving focus into the date range popover for Escape
  • copyButton gains the icon-2xs size; attributeFilterAction loses its unused icon option

c358bbb · What was checked, coverage and telemetry details are on the Maple / review check. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@Makisuo
Makisuo merged commit 84b9acb into main Nov 10, 2026
29 checks passed
@Makisuo
Makisuo deleted the audit-log-ui/e-design-pass branch November 10, 2026 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant