Backup Job Dashboard Cards#
Overview#
BackupCard is the primary UI component for rendering individual backup job entries in the dashboard. It wraps a <Link> that navigates to /backups/$backupId and renders a shadcn-style Card with two regions: a header (job identity + status) and a content area (schedule/timing rows).
Source: backup-card.tsx
Component Structure#
The card is divided into two sections :
Header (CardHeader)#
Contains two rows:
- Title row — A
CalendarClockicon + the schedule name (schedule.name) truncated withtruncate, and aBackupStatusDotpinned to the right withshrink-0. - Description row — A compact source→destination breadcrumb using
HardDriveicon +schedule.volume.name→Databaseicon +schedule.repository.name, both names usingfont-mono truncate.
Content (CardContent)#
Three key–value rows, each using the dashed-border spacer pattern :
| Row | Left label | Right value |
|---|---|---|
| Schedule | "Schedule" | schedule.cronExpression or "Manual only" in a <code> chip with max-w-[60%] truncate and a title attribute tooltip showing the full cron expression on hover |
| Last backup | "Last backup" | <TimeAgo> relative timestamp |
| Next backup | "Next backup" | formatShortDateTime(schedule.nextBackupAt) |
The dashed spacer (flex-1 border-b border-dashed) fills the gap between label and value.
Status Indicator#
BackupStatusDot accepts enabled, hasError, hasWarning, and isInProgress props derived from schedule.lastBackupStatus . It maps these to a StatusDot variant (success | neutral | error | warning | info) with priority: in_progress → error → warning → enabled → paused .
Text Overflow & Flexbox Patterns#
Long volume or repository names require careful overflow control. Key patterns enforced across the card :
min-w-0on flex containers — allows flex children to shrink below their natural width; without this,truncateon children has no effect. The<Link>wrapper,<Card>, and<CardContent>all usemin-w-0to ensure proper overflow handling in nested flex/grid layouts.shrink-0on icons and separators — theHardDriveicon,→arrow, andDatabaseicon will never shrink, keeping them visible even when names are very long .truncateon text nodes — volume and repository name<span>s truncate with ellipsis rather than overflowing .flex-1 min-w-0 w-0on the title flex child — used in the title row so the schedule name truncates before pushing the status dot off-screen .max-w-[60%] truncatewithtitleattribute on cron expression chip — long cron expressions are truncated at 60% of the container width with an ellipsis, while thetitle={schedule.cronExpression || undefined}provides a tooltip showing the full expression on hover.
The pattern min-w-0 on container + shrink-0 on chrome elements + truncate on text is the standard approach used throughout the codebase for long-content flex rows.
Data Model#
BackupCard takes a single schedule: BackupSchedule prop. BackupSchedule is a type alias for GetBackupScheduleResponse from the generated API client . Relevant fields used by this component:
shortId,name,enabled,cronExpressionlastBackupAt,lastBackupStatus(success | error | in_progress | warning | null)nextBackupAtvolume.name,repository.name
Related Files#
| File | Purpose |
|---|---|
backup-card.tsx | Main card component |
backup-status-dot.tsx | Status indicator dot |
time-ago.tsx | Relative timestamp display |
types.ts | BackupSchedule type alias |
PRs:
- PR #430 – fix dot invisible if volume name too long — added
min-w-0+shrink-0pattern to description row - PR #1051 – fix cron expression overflowing — changed cron expression chip from
shrink-0tomax-w-[60%] truncatewith tooltip; addedmin-w-0to<Link>,<Card>,<CardContent>, and schedule row container - PR #282 – responsive fixes — migrated arbitrary pixel values to Tailwind spacing scale; added container-query (
@container/@md:) support to parent layouts