import type { ProcessDefinitionView } from '../api/types'
import type { Token } from '../api/types'
import { useTraceStore } from '../store/traceStore'
interface ProcessDiagramPanelProps {
definition: ProcessDefinitionView | null
tokens: Token[]
loading: boolean
}
const TOKEN_STATUS_COLOR: Record<string, string> = {
Ready: 'var(--token-ready)',
Executing: 'var(--token-executing)',
Waiting: 'var(--token-waiting)',
Completed: 'var(--token-completed)',
Terminated: 'var(--token-terminated)',
Created: 'var(--token-created)',
Suspended: 'var(--token-suspended)',
}
export function ProcessDiagramPanel({ definition, tokens, loading }: ProcessDiagramPanelProps) {
const { setTokenFilter } = useTraceStore()
if (loading) {
return (
<div className="process-diagram-panel">
<div className="panel-placeholder">Loading diagram...</div>
</div>
)
}
if (!definition) {
return (
<div className="process-diagram-panel">
<div className="panel-placeholder">No process definition</div>
</div>
)
}
const nodeIds = new Set(definition.nodes.map((n) => n.id))
const tokensByNode = tokens.reduce<Record<string, Token[]>>((acc, t) => {
if (nodeIds.has(t.node_id)) {
acc[t.node_id] = acc[t.node_id] ?? []
acc[t.node_id].push(t)
}
return acc
}, {})
return (
<div className="process-diagram-panel">
<div className="diagram-graph">
<div className="diagram-nodes">
{definition.nodes.map((node) => {
const nodeTokens = tokensByNode[node.id] ?? []
const hasToken = nodeTokens.length > 0
return (
<div
key={node.id}
className={`diagram-node ${hasToken ? 'has-token' : ''}`}
data-node-id={node.id}
>
<span className="node-type">{node.node_type}</span>
<span className="node-id">{node.id}</span>
{nodeTokens.length > 0 && (
<div className="token-badges">
{nodeTokens.map((t) => (
<button
key={t.id}
type="button"
className="token-badge"
style={{
borderColor: TOKEN_STATUS_COLOR[t.status] ?? '#888',
}}
onClick={() => setTokenFilter(t.id)}
title={`${t.id} (${t.status})`}
>
{t.id.slice(0, 8)} {t.status}
</button>
))}
</div>
)}
</div>
)
})}
</div>
<div className="diagram-edges">
{definition.edges.map((e, i) => (
<div
key={`${e.source}-${e.target}-${i}`}
className="diagram-edge"
data-source={e.source}
data-target={e.target}
>
{e.source} → {e.target}
</div>
))}
</div>
</div>
</div>
)
}