The backend identity rename (applicationName → applicationId, agentId → instanceId) was not reflected in the frontend. This caused drilldown to fail (detail.applicationName was undefined, disabling the diagram fetch) and various display issues. Updated schema.d.ts, ExchangeHeader, ExecutionDiagram, Dashboard, AgentHealth, AgentInstance, LayoutShell, LogTab, InfoTab, DetailPanel, ExchangesPage, and tracing-store. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
116 lines
4.0 KiB
TypeScript
116 lines
4.0 KiB
TypeScript
import { Badge } from '@cameleer/design-system';
|
|
import type { ProcessorNode, ExecutionDetail } from '../types';
|
|
import { attributeBadgeColor } from '../../../utils/attribute-color';
|
|
import styles from '../ExecutionDiagram.module.css';
|
|
|
|
interface InfoTabProps {
|
|
processor: ProcessorNode | null;
|
|
executionDetail: ExecutionDetail;
|
|
}
|
|
|
|
function formatTime(iso: string | undefined): string {
|
|
if (!iso) return '-';
|
|
try {
|
|
const d = new Date(iso);
|
|
const h = String(d.getHours()).padStart(2, '0');
|
|
const m = String(d.getMinutes()).padStart(2, '0');
|
|
const s = String(d.getSeconds()).padStart(2, '0');
|
|
const ms = String(d.getMilliseconds()).padStart(3, '0');
|
|
return `${h}:${m}:${s}.${ms}`;
|
|
} catch {
|
|
return iso;
|
|
}
|
|
}
|
|
|
|
function formatDuration(ms: number | undefined): string {
|
|
if (ms === undefined || ms === null) return '-';
|
|
if (ms < 1000) return `${ms}ms`;
|
|
return `${(ms / 1000).toFixed(1)}s`;
|
|
}
|
|
|
|
function statusClass(status: string): string {
|
|
const s = status?.toUpperCase();
|
|
if (s === 'COMPLETED') return styles.statusCompleted;
|
|
if (s === 'FAILED') return styles.statusFailed;
|
|
return '';
|
|
}
|
|
|
|
function Field({ label, value, mono }: { label: string; value: string; mono?: boolean }) {
|
|
return (
|
|
<div>
|
|
<div className={styles.fieldLabel}>{label}</div>
|
|
<div className={mono ? styles.fieldValueMono : styles.fieldValue}>{value || '-'}</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Attributes({ attrs }: { attrs: Record<string, string> | undefined }) {
|
|
if (!attrs) return null;
|
|
const entries = Object.entries(attrs);
|
|
if (entries.length === 0) return null;
|
|
|
|
return (
|
|
<div className={styles.attributesSection}>
|
|
<div className={styles.attributesLabel}>Attributes</div>
|
|
<div className={styles.attributesList}>
|
|
{entries.map(([k, v]) => (
|
|
<Badge key={k} label={`${k}: ${v}`} color={attributeBadgeColor(String(v))} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function InfoTab({ processor, executionDetail }: InfoTabProps) {
|
|
if (processor) {
|
|
return (
|
|
<div>
|
|
<div className={styles.infoGrid}>
|
|
<Field label="Processor ID" value={processor.processorId} mono />
|
|
<Field label="Type" value={processor.processorType} />
|
|
<div>
|
|
<div className={styles.fieldLabel}>Status</div>
|
|
<span className={`${styles.statusBadge} ${statusClass(processor.status)}`}>
|
|
{processor.status}
|
|
</span>
|
|
</div>
|
|
|
|
<Field label="Start Time" value={formatTime(processor.startTime)} mono />
|
|
<Field label="End Time" value={formatTime(processor.endTime)} mono />
|
|
<Field label="Duration" value={formatDuration(processor.durationMs)} mono />
|
|
|
|
<Field label="Endpoint URI" value={processor.processorType} />
|
|
<Field label="Resolved URI" value={processor.resolvedEndpointUri ?? '-'} mono />
|
|
<div />
|
|
</div>
|
|
<Attributes attrs={processor.attributes} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Exchange-level view
|
|
return (
|
|
<div>
|
|
<div className={styles.infoGrid}>
|
|
<Field label="Execution ID" value={executionDetail.executionId} mono />
|
|
<Field label="Correlation ID" value={executionDetail.correlationId} mono />
|
|
<Field label="Exchange ID" value={executionDetail.exchangeId} mono />
|
|
|
|
<Field label="Application" value={executionDetail.applicationId} />
|
|
<Field label="Route ID" value={executionDetail.routeId} />
|
|
<div>
|
|
<div className={styles.fieldLabel}>Status</div>
|
|
<span className={`${styles.statusBadge} ${statusClass(executionDetail.status)}`}>
|
|
{executionDetail.status}
|
|
</span>
|
|
</div>
|
|
|
|
<Field label="Start Time" value={formatTime(executionDetail.startTime)} mono />
|
|
<Field label="End Time" value={formatTime(executionDetail.endTime)} mono />
|
|
<Field label="Duration" value={formatDuration(executionDetail.durationMs)} mono />
|
|
</div>
|
|
<Attributes attrs={executionDetail.attributes} />
|
|
</div>
|
|
);
|
|
}
|