Freshness diagnostics API, UI trust notes, mission control/stats updates, and deploy scripts.
Made-with: Cursor
This commit is contained in:
85
frontend/src/components/common/FreshnessTrustNote.tsx
Normal file
85
frontend/src/components/common/FreshnessTrustNote.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import type { MissionControlBridgeStatusResponse } from '@/services/api/missionControl'
|
||||
import type { ExplorerStats } from '@/services/api/stats'
|
||||
import type { ChainActivityContext } from '@/utils/activityContext'
|
||||
import {
|
||||
resolveFreshnessSourceLabel,
|
||||
summarizeFreshnessConfidence,
|
||||
} from '@/utils/explorerFreshness'
|
||||
import { formatRelativeAge } from '@/utils/format'
|
||||
|
||||
function buildSummary(context: ChainActivityContext) {
|
||||
if (context.transaction_visibility_unavailable) {
|
||||
return 'Chain-head visibility is current, while transaction freshness is currently unavailable.'
|
||||
}
|
||||
|
||||
if (context.state === 'active') {
|
||||
return 'Chain head and latest indexed transactions are closely aligned.'
|
||||
}
|
||||
|
||||
if (context.head_is_idle) {
|
||||
return 'Chain head is current, while latest visible transactions trail the tip.'
|
||||
}
|
||||
|
||||
if (context.state === 'low' || context.state === 'inactive') {
|
||||
return 'Chain head is current, and recent visible transaction activity is sparse.'
|
||||
}
|
||||
|
||||
return 'Freshness context is based on the latest visible public explorer evidence.'
|
||||
}
|
||||
|
||||
function buildDetail(context: ChainActivityContext) {
|
||||
if (context.transaction_visibility_unavailable) {
|
||||
return 'Use chain-head visibility and the last non-empty block as the current trust anchors.'
|
||||
}
|
||||
|
||||
const latestTxAge = formatRelativeAge(context.latest_transaction_timestamp)
|
||||
const latestNonEmptyBlock =
|
||||
context.last_non_empty_block_number != null ? `#${context.last_non_empty_block_number.toLocaleString()}` : 'unknown'
|
||||
|
||||
if (context.head_is_idle) {
|
||||
return `Latest visible transaction: ${latestTxAge}. Last non-empty block: ${latestNonEmptyBlock}.`
|
||||
}
|
||||
|
||||
if (context.state === 'active') {
|
||||
return `Latest visible transaction: ${latestTxAge}. Recent indexed activity remains close to the tip.`
|
||||
}
|
||||
|
||||
return `Latest visible transaction: ${latestTxAge}. Recent head blocks may be quiet even while the chain remains current.`
|
||||
}
|
||||
|
||||
export default function FreshnessTrustNote({
|
||||
context,
|
||||
stats,
|
||||
bridgeStatus,
|
||||
scopeLabel,
|
||||
className = '',
|
||||
}: {
|
||||
context: ChainActivityContext
|
||||
stats?: ExplorerStats | null
|
||||
bridgeStatus?: MissionControlBridgeStatusResponse | null
|
||||
scopeLabel?: string
|
||||
className?: string
|
||||
}) {
|
||||
const sourceLabel = resolveFreshnessSourceLabel(stats, bridgeStatus)
|
||||
const confidenceBadges = summarizeFreshnessConfidence(stats, bridgeStatus)
|
||||
const normalizedClassName = className ? ` ${className}` : ''
|
||||
|
||||
return (
|
||||
<div className={`rounded-2xl border border-gray-200 bg-white/80 px-4 py-3 text-sm dark:border-gray-800 dark:bg-gray-950/40${normalizedClassName}`}>
|
||||
<div className="font-medium text-gray-900 dark:text-white">{buildSummary(context)}</div>
|
||||
<div className="mt-1 text-gray-600 dark:text-gray-400">
|
||||
{buildDetail(context)} {scopeLabel ? `${scopeLabel}. ` : ''}{sourceLabel}
|
||||
</div>
|
||||
<div className="mt-2 flex flex-wrap gap-2 text-xs text-gray-500 dark:text-gray-400">
|
||||
{confidenceBadges.map((badge) => (
|
||||
<span
|
||||
key={badge}
|
||||
className="rounded-full border border-gray-200 bg-gray-50 px-2.5 py-1 dark:border-gray-700 dark:bg-gray-900/70"
|
||||
>
|
||||
{badge}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user