// One service snapshot supplies this entire card. Favorites never leave settings. import { useEffect, useState } from 'react'; import { useSessionSelector } from '../../context/SessionContext.jsx'; import { isFeatureEnabled } from '../../lib/features.js'; import { useSocket } from '../../context/SocketContext.jsx'; import { useSettingsNamespace } from '../../settings/index.js'; import CardFrame from '../CardFrame/index.jsx'; import { fieldClass } from './constants.js'; const display = (value) => value == null ? 'Unavailable' : String(value); const bytes = (value) => value == null ? 'Unavailable' : `${(value / 1024 ** 2).toFixed(1)} MiB`; const time = (value) => value ? new Date(value).toLocaleString() : 'Unavailable'; const age = (now, value) => value ? `${Math.max(0, (now - value) / 1000).toFixed(1)} s` : 'Unavailable'; function Row({ label, children }) { return
{session ? `${session.modelName} · ${session.status}` : state ? 'Stopped' : 'Waiting for rover learning status…'}
{session.predictionStatus || 'Waiting for fresh video and sensors'}
{status === 'issued' ? 'Submitted' : status}
{state.control.reason}
}Recording: {recording ? recording.paused ? 'paused for disk space' : `${recording.sessions.filter((item) => item.video === 'Recording human driving').length} driving · ${recording.sessions.filter((item) => item.video === 'Dock lead-in buffer').length} dock buffer(s)` : 'unavailable'} · Training: {training?.status || 'unavailable'}
{(error || state?.catalogError) &&{error || state.catalogError}
}