Skip to content

Commit 3ecbf4e

Browse files
Dumbrisclaude
andauthored
feat(webui): calmer, more compact Activity Log (#1024)
* fix(webui): quiet the Activity Log — de-colour success, compact header, real Intent column The Activity Log spent its loudest signals on its most common outcome. Success rows carried a green pill, five stat cards plus a permanently open nine-control filter grid pushed the first row below the fold, "code_execution" was printed twice on the same line, and the Intent column was a 52px slot holding a coloured `read` pill whose glyph overflowed it — with the declared REASON hidden in a tooltip. Semantic colour is now reserved for states that need attention: - Status renders through a new pure `statusPresentation(status)` helper — success is plain muted text (no pill, no green), error keeps a red pill, blocked an amber one, rejected and any other oddity a neutral grey chip. Applied to the table column, the detail drawer and ActivityWidget from one shared mapping. The Success and Rejected KPI values lost their colour too. - The `code_execution` marker appears once per row: the Type-column badge is dropped when the Details column already prints the same word (a quiet 🧩 glyph sits beside that text instead), and the child badge is ghost/muted context rather than an accent alert. - The page opens on ONE compact strip: "54 calls · 6 errors · 1 blocked" (zeros omitted, only error/blocked coloured, each segment still driving the Status filter per #436), a Filters toggle with an active-filter count badge, Export, and the active filters as dismissable chips — visible even collapsed. The stat cards and the filter grid render only when expanded; the choice is persisted in localStorage behind try/catch and defaults to collapsed. - Intent is a real column: an operation glyph followed by the reason on one line, ellipsised, with the full text in `title`. No colour pill, no clipped icon; a muted dash when nothing was declared. Parent/child navigation, every existing filter and SSE live updates are unchanged. New pure helpers (`statusPresentation`, `intentPresentation`, `compactSummaryParts`, `activeFilterChips`, `activityDetailsText`, `showParentBadgeInTypeColumn`) live in utils/activity.ts, which also absorbed the type/status/intent maps that Activity.vue and ActivityWidget.vue had been duplicating locally. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(webui): severity chip is active only while sensitive-data filter is Detected Cross-review finding on #1024: filtering applies severity only when the sensitive-data filter is 'true', but the compact strip chipped and counted a leftover severity value after sensitive-data was switched off — the collapsed UI claimed a filter that wasn't narrowing anything. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent f99ba88 commit 3ecbf4e

5 files changed

Lines changed: 1186 additions & 179 deletions

File tree

‎frontend/src/components/ActivityWidget.vue‎

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
</div>
2020
<div class="stat py-2 px-4">
2121
<div class="stat-title text-xs">Success</div>
22-
<div class="stat-value text-lg text-success">{{ summary.success_count }}</div>
22+
<!-- Success is the norm — it gets no colour, so Errors can have it. -->
23+
<div class="stat-value text-lg text-base-content/70">{{ summary.success_count }}</div>
2324
</div>
2425
<div class="stat py-2 px-4">
2526
<div class="stat-title text-xs">Errors</div>
@@ -67,23 +68,25 @@
6768
<div class="flex items-center gap-2">
6869
<div class="text-xs text-base-content/60">{{ formatRelativeTime(activity.timestamp) }}</div>
6970
<!-- Sub-call of a code_execution run (see utils/activity). -->
71+
<!-- Context, not an alert: ghost chip, muted text. -->
7072
<span
7173
v-if="isChildCall(activity)"
7274
data-test="widget-child-badge"
73-
class="badge badge-xs badge-ghost"
75+
class="badge badge-xs badge-ghost font-normal text-base-content/60"
7476
title="Sub-call dispatched by a code_execution run"
7577
>
7678
↳ via code_execution
7779
</span>
7880
</div>
7981
</div>
8082
</div>
81-
<div
82-
class="badge badge-sm"
83-
:class="getStatusBadgeClass(activity.status)"
83+
<!-- Same quiet-success treatment as the Activity Log table. -->
84+
<span
85+
data-test="widget-activity-status"
86+
:class="statusPresentation(activity.status).className"
8487
>
85-
{{ activity.status }}
86-
</div>
88+
{{ statusPresentation(activity.status).label }}
89+
</span>
8790
</div>
8891
</div>
8992
</div>
@@ -95,7 +98,12 @@ import { ref, onMounted } from 'vue'
9598
import { useRouter } from 'vue-router'
9699
import api from '@/services/api'
97100
import type { ActivityRecord, ActivitySummaryResponse } from '@/types/api'
98-
import { formatPreflightSummary, isChildCall, isPreflightActivity } from '@/utils/activity'
101+
import {
102+
formatPreflightSummary,
103+
isChildCall,
104+
isPreflightActivity,
105+
statusPresentation,
106+
} from '@/utils/activity'
99107
100108
const router = useRouter()
101109
@@ -160,17 +168,6 @@ const getTypeIcon = (type: string): string => {
160168
return typeIcons[type] || '📋'
161169
}
162170
163-
const getStatusBadgeClass = (status: string): string => {
164-
const statusClasses: Record<string, string> = {
165-
'success': 'badge-success',
166-
'error': 'badge-error',
167-
'blocked': 'badge-warning',
168-
// Spec 093: shed by a concurrency limit (backpressure, not an upstream fault).
169-
'rejected': 'badge-info'
170-
}
171-
return statusClasses[status] || 'badge-ghost'
172-
}
173-
174171
// Lifecycle
175172
onMounted(() => {
176173
loadData()

0 commit comments

Comments
 (0)