import type { ReactNode } from "react"; import { XYZAC_KINEMATICS, type XyzacOperationTrace, type XyzacPanelView } from "./xyzac-panel-contract"; type Command = (kind: string, payload?: Record, action?: string) => void; export function XyzacKinematicsControl({ view, command }: { view: XyzacPanelView; command: Command }) { const active = view.kinematics?.active_type; return
Switchkins{view.kinematics?.native_type ?? "Unavailable"}
{XYZAC_KINEMATICS.map((item) => { const gate = view.gates[item.action]; const disabled = view.status !== "ready" || gate?.enabled === false; return ; })}
; } export function XyzacManualPanel({ view }: { view: XyzacPanelView }) { const pose = view.pose; const axes = ["x", "y", "z", "a", "c"] as const; return
XYZAC authority{view.kinematics?.linear_units ?? "mm"} / {view.kinematics?.angular_units ?? "deg"}
{axes.map((axis, index) =>
{axis.toUpperCase()}{pose ? Number(pose[axis] ?? Number.NaN).toFixed(axis === "a" || axis === "c" ? 3 : 4) : "-"}J{index} {view.joints.length === 5 ? Number(view.joints[index]).toFixed(4) : "-"}
)}
Tool {view.kinematics ? Number(view.kinematics.offsets.tool_offset).toFixed(3) : "-"}Y offset {view.kinematics ? Number(view.kinematics.offsets.y_offset).toFixed(3) : "-"}Z offset {view.kinematics ? Number(view.kinematics.offsets.z_offset).toFixed(3) : "-"}
; } export function XyzacProgramPane({ status, currentLine, sourceHash, children }: { status: string; currentLine: number | null; sourceHash?: string | null; children: ReactNode }) { return
XYZAC Program{status}Line {currentLine ?? "-"}{sourceHash?.slice(0, 18) ?? "no source"}
{children}
; } export function XyzacDiagnostics({ view, operations, alarms, error }: { view: XyzacPanelView; operations: XyzacOperationTrace[]; alarms: Array>; error: { code: string; message?: string } | null }) { const disabled = Object.entries(view.gates).filter(([, gate]) => gate.enabled === false); return
{view.status.toUpperCase()}Tick {view.tick}{view.stateHash || "no hash"}
{error &&
{error.code}{error.message}
}

Operation trace

{operations.length ? operations.slice(-8).reverse().map((item, index) =>
{item.operation_id ?? "-"}{item.kind}{item.phase}{item.reason ?? item.response_kind}
) : No operations}

Alarms / recovery

{alarms.length ? alarms.slice(-5).map((alarm, index) =>
{String(alarm.code ?? "alarm")}{String(alarm.severity ?? "error")}
) : No alarms}
recovery{view.recovery ? JSON.stringify(view.recovery) : "idle"}

Gate reasons

{disabled.length ? disabled.slice(0, 10).map(([name, gate]) =>
{name}{gate.reason}
) : All XYZAC gates enabled}
; } export function XyzacTrtPanel({ view, command }: { view: XyzacPanelView; command: Command }) { return
; }