guibranco / guibranco/logstream-ui
[FEATURE] Client health indicators in Applications screen
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 0
- Avg merge
- 15m
- Merged PRs (30d)
- 49
Description
## Summary
Show real-time health status (active / silent / never seen) and last-seen timestamp for each registered client in the Applications screen, surfacing dead or silent clients immediately.
> **Depends on:** [`[FEATURE] Client health monitoring and last-seen tracking`](https://github.com/guibranco/logstream-server/issues) in `guibranco/logstream-server`
## Motivation
Operators currently have no way to tell from the UI whether a registered application is actively sending logs or has gone silent. This is especially important for detecting failed deployments or misconfigured applications.
## Proposed changes
### ClientTable β updated columns
| Column | Before | After |
|--------|--------|-------|
| **Status** | Active / Inactive pill | Active / Silent / Never seen pill |
| **Last seen** | β (new column) | "3 min ago" / "2 hours ago" / "Never" |
Status pill colours:
- π’ **Active** β last seen within the heartbeat timeout
- π‘ **Silent** β last seen, but exceeded the heartbeat timeout
- β« **Never seen** β `last_seen_at` is null (registered but never ingested)
- π΄ **Inactive** β `active: false` (manually disabled)
### Client detail drawer β health section
In the edit drawer, below the Active toggle:
```
ββ Health monitoring βββββββββββββββββββββββββ
Last seen: 3 minutes ago
Heartbeat timeout: [10] minutes
Alert if silent longer than this.
Leave blank to disable monitoring.
ββββββββββββββββββββββββββββββββββββββββββββββ
```
### Tooltip on Silent status pill
```
Last seen: 2026-04-17 14:22:00
Silence threshold: 10 minutes
Silent for: 47 minutes
```
## Files to modify / create
- `src/components/clients/ClientTable.tsx` β Last seen column, updated Status pill
- `src/components/clients/ClientStatusPill.tsx` β new component with active/silent/never-seen/inactive states
- `src/components/clients/ClientForm.tsx` β heartbeat timeout field in health section
- `src/hooks/useClients.ts` β include `last_seen_at`, `status`, `heartbeat_timeout_min` in responses
## UX details
- "Last seen" displays as a relative time ("3 min ago") with the absolute timestamp in a tooltip
- Relative time auto-updates every 60 seconds without a server refetch
- The client list auto-refreshes every 30 seconds to pick up new `last_seen_at` values
- Silent clients appear first in the table (sorted by urgency: inactive β silent β never_seen β active)
## Acceptance criteria
- [ ] Last seen column added to client table
- [ ] Status pill shows Active / Silent / Never seen / Inactive states with correct colours
- [ ] Tooltip on Silent pill shows last seen timestamp, threshold, and silence duration
- [ ] Heartbeat timeout field in edit drawer
- [ ] Relative time auto-updates every 60 s
- [ ] Client list auto-refreshes every 30 s
- [ ] Silent clients sorted to top of table
Contributor guide
Research direction
Start with src/components/clients/ClientTable.tsx, ClientStatusPill.tsx, ClientForm.tsx, and src/hooks/useClients.ts to trace the current client data and status handling. Check how the dependent server issue exposes last_seen_at, status, and heartbeat_timeout_min before wiring the listed UI changes. Done means all acceptance criteria pass, including tooltips, relative-time updates, polling, and urgency sorting.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript, vite
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100