feat(frontend): RawSegmentsPanel collapsible debug aid
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import React from "react";
|
||||
import type { ClaimDetail } from "@/types";
|
||||
|
||||
type RawSegmentsPanelProps = {
|
||||
rawSegments: ClaimDetail["rawSegments"];
|
||||
};
|
||||
|
||||
/**
|
||||
* Format a single segment by joining its elements with `*` (the X12
|
||||
* element separator). Trailing/leading whitespace inside individual
|
||||
* elements is preserved — these strings come straight off the parser
|
||||
* and any trimming would change the visible byte-for-byte content.
|
||||
*/
|
||||
function formatSegment(elements: string[]): string {
|
||||
return elements.join("*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw-segments debug section of the claim detail drawer (SP4).
|
||||
*
|
||||
* Renders the exact X12 segment strings the parser saw, collapsed by
|
||||
* default behind a native <details>/<summary> so the user can opt in
|
||||
* to a wall of monospace when they're debugging. Element separator is
|
||||
* `*` and segment terminator is implicit at the end of each line —
|
||||
* matches what the parser produces. This is a read-only diagnostic;
|
||||
* the plan keeps it intentionally simple (no copy button for v1).
|
||||
*/
|
||||
export function RawSegmentsPanel({ rawSegments }: RawSegmentsPanelProps) {
|
||||
return (
|
||||
<section
|
||||
className="flex flex-col gap-3 px-6 py-4"
|
||||
data-testid="raw-segments-panel"
|
||||
>
|
||||
<h3
|
||||
data-testid="section-label"
|
||||
className="text-[10.5px] font-semibold uppercase tracking-[0.18em] text-[color:var(--m-ink-tertiary)]"
|
||||
>
|
||||
Raw Segments ({rawSegments.length})
|
||||
</h3>
|
||||
|
||||
<details className="rounded-lg border border-[color:var(--m-border-heavy)]/15 bg-[color:var(--m-surface)]">
|
||||
<summary
|
||||
className="cursor-pointer select-none px-4 py-2 text-sm text-[color:var(--m-ink-secondary)] hover:text-[color:var(--m-ink-primary)]"
|
||||
data-testid="raw-segments-summary"
|
||||
>
|
||||
{rawSegments.length === 0
|
||||
? "Show raw segments"
|
||||
: "Show raw segments"}
|
||||
</summary>
|
||||
|
||||
{rawSegments.length === 0 ? (
|
||||
<p
|
||||
data-testid="raw-segments-empty"
|
||||
className="px-4 pb-3 text-sm text-[color:var(--m-ink-tertiary)]"
|
||||
>
|
||||
No segments
|
||||
</p>
|
||||
) : (
|
||||
<pre
|
||||
data-testid="raw-segments-pre"
|
||||
className="overflow-x-auto whitespace-pre-wrap px-4 pb-3 pt-1 text-[12px] leading-relaxed text-[color:var(--m-ink-primary)] font-mono"
|
||||
style={{ fontFamily: "var(--m-font-mono)" }}
|
||||
>
|
||||
{rawSegments.map((segment, i) => (
|
||||
<React.Fragment key={i}>
|
||||
{i > 0 ? "\n" : null}
|
||||
<span data-testid="raw-segment-line">{formatSegment(segment)}</span>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</pre>
|
||||
)}
|
||||
</details>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user