Skip to content

Commit 36fec8b

Browse files
authored
Render all columns in irregular CSV responses (#584)
1 parent 115615d commit 36fec8b

2 files changed

Lines changed: 44 additions & 6 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type { ReactNode } from "react";
2+
import { renderToStaticMarkup } from "react-dom/server";
3+
import { describe, expect, test, vi } from "vite-plus/test";
4+
import { CsvViewerInner } from "./CsvViewer";
5+
6+
vi.mock("@yaakapp-internal/ui", () => ({
7+
Table: ({ children }: { children: ReactNode }) => <table>{children}</table>,
8+
TableBody: ({ children }: { children: ReactNode }) => <tbody>{children}</tbody>,
9+
TableCell: ({ children }: { children: ReactNode }) => <td>{children}</td>,
10+
TableHead: ({ children }: { children: ReactNode }) => <thead>{children}</thead>,
11+
TableHeaderCell: ({ children }: { children: ReactNode }) => <th>{children}</th>,
12+
TableRow: ({ children }: { children: ReactNode }) => <tr>{children}</tr>,
13+
}));
14+
15+
describe("CsvViewer", () => {
16+
test("renders columns that extend beyond the first row", () => {
17+
const markup = renderToStaticMarkup(
18+
<CsvViewerInner
19+
text={[
20+
"startDate,2026-02-03T00:00-03:00",
21+
"endDate,2026-02-03T23:59:59-03:00",
22+
"id,Fecha de inicio,Nombre,Estado,Perfil de puesto,ID de sucursal,Sucursal,Fecha de fin,ID de usuario",
23+
"391118210,2026-02-03 12:58:55,atencion1,Disponible,ATD,3549,sucursal,2026-02-03 12:59:08,42041",
24+
].join("\n")}
25+
/>,
26+
);
27+
28+
expect(markup).toContain("ID de usuario");
29+
expect(markup).toContain("42041");
30+
expect(markup.match(/<td>/g)).toHaveLength(20);
31+
});
32+
});

apps/yaak-client/components/responseViewers/CsvViewer.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,33 @@ export function CsvViewer({ text, className }: Props) {
2626
export function CsvViewerInner({ text, className }: { text: string | null; className?: string }) {
2727
const parsed = useMemo(() => {
2828
if (text == null) return null;
29-
return Papa.parse<Record<string, string>>(text, { header: true, skipEmptyLines: true });
29+
return Papa.parse<string[]>(text, { skipEmptyLines: true });
3030
}, [text]);
3131

3232
if (parsed === null) return null;
3333

34+
const header = parsed.data[0] ?? [];
35+
const rows = parsed.data.slice(1);
36+
const columnCount = parsed.data.reduce((count, row) => Math.max(count, row.length), 0);
37+
const columnIndexes = Array.from({ length: columnCount }, (_, index) => index);
38+
3439
return (
3540
<div className="overflow-auto h-full">
3641
<Table className={classNames(className, "text-sm")}>
3742
<TableHead>
3843
<TableRow>
39-
{parsed.meta.fields?.map((field) => (
40-
<TableHeaderCell key={field}>{field}</TableHeaderCell>
44+
{columnIndexes.map((columnIndex) => (
45+
<TableHeaderCell key={columnIndex}>{header[columnIndex] ?? ""}</TableHeaderCell>
4146
))}
4247
</TableRow>
4348
</TableHead>
4449
<TableBody>
45-
{parsed.data.map((row, i) => (
50+
{rows.map((row, i) => (
4651
// oxlint-disable-next-line react/no-array-index-key
4752
<TableRow key={i}>
48-
{parsed.meta.fields?.map((key) => (
49-
<TableCell key={key}>{row[key] ?? ""}</TableCell>
53+
{row.map((cell, columnIndex) => (
54+
// oxlint-disable-next-line react/no-array-index-key
55+
<TableCell key={columnIndex}>{cell}</TableCell>
5056
))}
5157
</TableRow>
5258
))}

0 commit comments

Comments
 (0)