mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-08-24 20:34:05 +02:00
Render all columns in irregular CSV responses (#584)
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
import type { ReactNode } from "react";
|
||||||
|
import { renderToStaticMarkup } from "react-dom/server";
|
||||||
|
import { describe, expect, test, vi } from "vite-plus/test";
|
||||||
|
import { CsvViewerInner } from "./CsvViewer";
|
||||||
|
|
||||||
|
vi.mock("@yaakapp-internal/ui", () => ({
|
||||||
|
Table: ({ children }: { children: ReactNode }) => <table>{children}</table>,
|
||||||
|
TableBody: ({ children }: { children: ReactNode }) => <tbody>{children}</tbody>,
|
||||||
|
TableCell: ({ children }: { children: ReactNode }) => <td>{children}</td>,
|
||||||
|
TableHead: ({ children }: { children: ReactNode }) => <thead>{children}</thead>,
|
||||||
|
TableHeaderCell: ({ children }: { children: ReactNode }) => <th>{children}</th>,
|
||||||
|
TableRow: ({ children }: { children: ReactNode }) => <tr>{children}</tr>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("CsvViewer", () => {
|
||||||
|
test("renders columns that extend beyond the first row", () => {
|
||||||
|
const markup = renderToStaticMarkup(
|
||||||
|
<CsvViewerInner
|
||||||
|
text={[
|
||||||
|
"startDate,2026-02-03T00:00-03:00",
|
||||||
|
"endDate,2026-02-03T23:59:59-03:00",
|
||||||
|
"id,Fecha de inicio,Nombre,Estado,Perfil de puesto,ID de sucursal,Sucursal,Fecha de fin,ID de usuario",
|
||||||
|
"391118210,2026-02-03 12:58:55,atencion1,Disponible,ATD,3549,sucursal,2026-02-03 12:59:08,42041",
|
||||||
|
].join("\n")}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(markup).toContain("ID de usuario");
|
||||||
|
expect(markup).toContain("42041");
|
||||||
|
expect(markup.match(/<td>/g)).toHaveLength(20);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -26,27 +26,33 @@ export function CsvViewer({ text, className }: Props) {
|
|||||||
export function CsvViewerInner({ text, className }: { text: string | null; className?: string }) {
|
export function CsvViewerInner({ text, className }: { text: string | null; className?: string }) {
|
||||||
const parsed = useMemo(() => {
|
const parsed = useMemo(() => {
|
||||||
if (text == null) return null;
|
if (text == null) return null;
|
||||||
return Papa.parse<Record<string, string>>(text, { header: true, skipEmptyLines: true });
|
return Papa.parse<string[]>(text, { skipEmptyLines: true });
|
||||||
}, [text]);
|
}, [text]);
|
||||||
|
|
||||||
if (parsed === null) return null;
|
if (parsed === null) return null;
|
||||||
|
|
||||||
|
const header = parsed.data[0] ?? [];
|
||||||
|
const rows = parsed.data.slice(1);
|
||||||
|
const columnCount = parsed.data.reduce((count, row) => Math.max(count, row.length), 0);
|
||||||
|
const columnIndexes = Array.from({ length: columnCount }, (_, index) => index);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overflow-auto h-full">
|
<div className="overflow-auto h-full">
|
||||||
<Table className={classNames(className, "text-sm")}>
|
<Table className={classNames(className, "text-sm")}>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{parsed.meta.fields?.map((field) => (
|
{columnIndexes.map((columnIndex) => (
|
||||||
<TableHeaderCell key={field}>{field}</TableHeaderCell>
|
<TableHeaderCell key={columnIndex}>{header[columnIndex] ?? ""}</TableHeaderCell>
|
||||||
))}
|
))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{parsed.data.map((row, i) => (
|
{rows.map((row, i) => (
|
||||||
// oxlint-disable-next-line react/no-array-index-key
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
<TableRow key={i}>
|
<TableRow key={i}>
|
||||||
{parsed.meta.fields?.map((key) => (
|
{row.map((cell, columnIndex) => (
|
||||||
<TableCell key={key}>{row[key] ?? ""}</TableCell>
|
// oxlint-disable-next-line react/no-array-index-key
|
||||||
|
<TableCell key={columnIndex}>{cell}</TableCell>
|
||||||
))}
|
))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Reference in New Issue
Block a user