import { useState } from 'react'; import { Badge } from '@cameleer/design-system'; import type { Deployment, AppVersion } from '../../../api/queries/admin/apps'; import { timeAgo } from '../../../utils/format-utils'; import styles from './AppDeploymentPage.module.css'; const FALLBACK_CAP = 10; interface CheckpointsTableProps { deployments: Deployment[]; versions: AppVersion[]; currentDeploymentId: string | null; jarRetentionCount: number | null; onSelect: (deploymentId: string) => void; } export function CheckpointsTable({ deployments, versions, currentDeploymentId, jarRetentionCount, onSelect, }: CheckpointsTableProps) { const [expanded, setExpanded] = useState(false); const versionMap = new Map(versions.map((v) => [v.id, v])); const checkpoints = deployments .filter((d) => d.deployedConfigSnapshot && d.id !== currentDeploymentId) .sort((a, b) => (b.deployedAt ?? '').localeCompare(a.deployedAt ?? '')); if (checkpoints.length === 0) { return
No past deployments yet.
; } const cap = (jarRetentionCount ?? 0) > 0 ? jarRetentionCount! : FALLBACK_CAP; const visible = expanded ? checkpoints : checkpoints.slice(0, cap); const hidden = checkpoints.length - visible.length; return (
{visible.map((d) => { const v = versionMap.get(d.appVersionId); const archived = !v; const strategyLabel = d.deploymentStrategy === 'BLUE_GREEN' ? 'blue/green' : 'rolling'; return ( onSelect(d.id)} > ); })}
Version JAR Deployed by Deployed Strategy Outcome
{v ? ( {v.jarFilename} ) : ( <> JAR pruned
archived — JAR pruned
)}
{d.createdBy ?? } {d.deployedAt && timeAgo(d.deployedAt)}
{d.deployedAt}
{strategyLabel} {d.status}
{hidden > 0 && !expanded && ( )}
); }