Improve explorer subsystem posture and wallet visibility

This commit is contained in:
defiQUG
2026-04-13 21:35:36 -07:00
parent b5a2e0c0a4
commit 251e37bd05
8 changed files with 315 additions and 3 deletions

View File

@@ -52,6 +52,11 @@ function buildDetail(context: ChainActivityContext, diagnosticExplanation?: stri
return `Latest visible transaction: ${latestTxAge}. Recent head blocks may be quiet even while the chain remains current.`
}
function normalizeSentence(value?: string | null): string {
if (!value) return ''
return value.trim().replace(/[.\s]+$/, '')
}
export default function FreshnessTrustNote({
context,
stats,
@@ -96,7 +101,9 @@ export default function FreshnessTrustNote({
<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, diagnosticExplanation)} {scopeLabel ? `${scopeLabel}. ` : ''}{sourceLabel}
{normalizeSentence(buildDetail(context, diagnosticExplanation))}.{' '}
{scopeLabel ? `${normalizeSentence(scopeLabel)}. ` : ''}
{normalizeSentence(sourceLabel)}.
</div>
<div className="mt-2 flex flex-wrap gap-2 text-xs text-gray-500 dark:text-gray-400">
{confidenceBadges.map((badge) => (

View File

@@ -0,0 +1,127 @@
import { Card } from '@/libs/frontend-ui-primitives'
import { useUiMode } from './UiModeContext'
import type { MissionControlSubsystemStatus } from '@/services/api/missionControl'
import { formatRelativeAge } from '@/utils/format'
function subsystemLabel(key: string): string {
const labels: Record<string, string> = {
rpc_head: 'RPC head',
tx_index: 'Transaction index',
stats_summary: 'Stats summary',
bridge_relay_monitoring: 'Bridge relay monitoring',
freshness_queries: 'Freshness queries',
}
return labels[key] || key.replace(/_/g, ' ')
}
function normalizeStatus(status?: string | null): string {
const normalized = String(status || '').toLowerCase()
if (!normalized) return 'unknown'
if (normalized === 'ok') return 'operational'
return normalized
}
function statusClasses(status?: string | null): string {
const normalized = normalizeStatus(status)
if (['degraded', 'down', 'stale'].includes(normalized)) {
return 'border-red-200 bg-red-50 text-red-700 dark:border-red-900/60 dark:bg-red-950/30 dark:text-red-200'
}
if (['warning', 'partial', 'paused'].includes(normalized)) {
return 'border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200'
}
if (normalized === 'operational') {
return 'border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-900/60 dark:bg-emerald-950/30 dark:text-emerald-200'
}
return 'border-gray-200 bg-gray-50 text-gray-700 dark:border-gray-700 dark:bg-gray-900/50 dark:text-gray-200'
}
function compactMeta(subsystem: MissionControlSubsystemStatus): string {
const parts = [
subsystem.source || null,
subsystem.completeness || null,
subsystem.confidence || null,
].filter(Boolean)
return parts.length > 0 ? parts.join(' · ') : 'No supporting freshness metadata'
}
export default function SubsystemPosturePanel({
subsystems,
title = 'Subsystem Posture',
scopeLabel,
preferredKeys,
className = '',
}: {
subsystems?: Record<string, MissionControlSubsystemStatus> | null
title?: string
scopeLabel?: string
preferredKeys?: string[]
className?: string
}) {
const { mode } = useUiMode()
const orderedEntries = Object.entries(subsystems || {})
.filter(([key]) => !preferredKeys || preferredKeys.includes(key))
.sort(([leftKey], [rightKey]) => {
const leftIndex = preferredKeys ? preferredKeys.indexOf(leftKey) : -1
const rightIndex = preferredKeys ? preferredKeys.indexOf(rightKey) : -1
if (leftIndex !== -1 || rightIndex !== -1) {
return (leftIndex === -1 ? Number.MAX_SAFE_INTEGER : leftIndex) - (rightIndex === -1 ? Number.MAX_SAFE_INTEGER : rightIndex)
}
return leftKey.localeCompare(rightKey)
})
if (orderedEntries.length === 0) {
return null
}
const normalizedClassName = className ? ` ${className}` : ''
return (
<Card className={`border border-gray-200 bg-white/80 dark:border-gray-800 dark:bg-gray-950/40${normalizedClassName}`} title={title}>
<div className="flex flex-col gap-4">
<div className="text-sm leading-6 text-gray-600 dark:text-gray-400">
{scopeLabel || 'These subsystem signals come from the same backend freshness model used to explain chain and transaction visibility.'}
</div>
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
{orderedEntries.map(([key, subsystem]) => {
const status = normalizeStatus(subsystem.status)
return (
<div
key={key}
className="rounded-2xl border border-gray-200 bg-gray-50/70 p-4 dark:border-gray-800 dark:bg-gray-900/40"
>
<div className="flex items-start justify-between gap-3">
<div>
<div className="text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
{subsystemLabel(key)}
</div>
<div className="mt-1 text-base font-semibold capitalize text-gray-900 dark:text-white">
{status}
</div>
</div>
<span className={`rounded-full border px-2.5 py-1 text-[11px] font-semibold uppercase tracking-wide ${statusClasses(status)}`}>
{status}
</span>
</div>
<div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
{subsystem.updated_at ? `Updated ${formatRelativeAge(subsystem.updated_at)}` : 'Update time unavailable'}
</div>
<div className="mt-2 text-xs leading-5 text-gray-500 dark:text-gray-400">
{compactMeta(subsystem)}
</div>
{mode === 'guided' && subsystem.provenance ? (
<div className="mt-2 text-xs leading-5 text-gray-500 dark:text-gray-400">
Provenance: {subsystem.provenance.replace(/_/g, ' ')}
</div>
) : null}
</div>
)
})}
</div>
</div>
</Card>
)
}