mirror of https://github.com/kortix-ai/suna.git
comment out for build
This commit is contained in:
parent
70e845c856
commit
d442352182
|
@ -1,190 +1,190 @@
|
||||||
"use client";
|
// "use client";
|
||||||
|
|
||||||
import { useState, useEffect, useMemo } from "react";
|
// import { useState, useEffect, useMemo } from "react";
|
||||||
import { readString } from "react-papaparse";
|
// import { readString } from "react-papaparse";
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
// import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
import {
|
// import {
|
||||||
Table,
|
// Table,
|
||||||
TableBody,
|
// TableBody,
|
||||||
TableCell,
|
// TableCell,
|
||||||
TableHead,
|
// TableHead,
|
||||||
TableHeader,
|
// TableHeader,
|
||||||
TableRow,
|
// TableRow,
|
||||||
} from "@/components/ui/table";
|
// } from "@/components/ui/table";
|
||||||
import { Input } from "@/components/ui/input";
|
// import { Input } from "@/components/ui/input";
|
||||||
import { Button } from "@/components/ui/button";
|
// import { Button } from "@/components/ui/button";
|
||||||
import { Search, ChevronLeft, ChevronRight } from "lucide-react";
|
// import { Search, ChevronLeft, ChevronRight } from "lucide-react";
|
||||||
import { cn } from "@/lib/utils";
|
// import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
interface CsvRendererProps {
|
// interface CsvRendererProps {
|
||||||
content: string;
|
// content: string;
|
||||||
className?: string;
|
// className?: string;
|
||||||
}
|
// }
|
||||||
|
|
||||||
interface ParsedCsvData {
|
// interface ParsedCsvData {
|
||||||
data: Record<string, string>[];
|
// data: Record<string, string>[];
|
||||||
headers: string[];
|
// headers: string[];
|
||||||
errors?: any[];
|
// errors?: any[];
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Define the PapaParse result interface
|
// // Define the PapaParse result interface
|
||||||
interface PapaParseResult {
|
// interface PapaParseResult {
|
||||||
data: Record<string, string>[];
|
// data: Record<string, string>[];
|
||||||
errors: { message: string; row: number }[];
|
// errors: { message: string; row: number }[];
|
||||||
meta: {
|
// meta: {
|
||||||
delimiter: string;
|
// delimiter: string;
|
||||||
linebreak: string;
|
// linebreak: string;
|
||||||
aborted: boolean;
|
// aborted: boolean;
|
||||||
truncated: boolean;
|
// truncated: boolean;
|
||||||
cursor: number;
|
// cursor: number;
|
||||||
fields: string[];
|
// fields: string[];
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function CsvRenderer({ content, className }: CsvRendererProps) {
|
// export function CsvRenderer({ content, className }: CsvRendererProps) {
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
// const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
// const [currentPage, setCurrentPage] = useState(1);
|
||||||
const rowsPerPage = 15;
|
// const rowsPerPage = 15;
|
||||||
|
|
||||||
// Parse CSV data
|
// // Parse CSV data
|
||||||
const parsedData = useMemo<ParsedCsvData>(() => {
|
// const parsedData = useMemo<ParsedCsvData>(() => {
|
||||||
if (!content) return { data: [], headers: [] };
|
// if (!content) return { data: [], headers: [] };
|
||||||
|
|
||||||
try {
|
// try {
|
||||||
let headers: string[] = [];
|
// let headers: string[] = [];
|
||||||
let data: Record<string, string>[] = [];
|
// let data: Record<string, string>[] = [];
|
||||||
|
|
||||||
readString(content, {
|
// readString(content, {
|
||||||
header: true,
|
// header: true,
|
||||||
skipEmptyLines: true,
|
// skipEmptyLines: true,
|
||||||
complete: (results: any) => {
|
// complete: (results: any) => {
|
||||||
if (results.errors && results.errors.length > 0) {
|
// if (results.errors && results.errors.length > 0) {
|
||||||
console.error("CSV parsing errors:", results.errors);
|
// console.error("CSV parsing errors:", results.errors);
|
||||||
}
|
// }
|
||||||
|
|
||||||
headers = results.meta.fields || [];
|
// headers = results.meta.fields || [];
|
||||||
data = results.data || [];
|
// data = results.data || [];
|
||||||
},
|
// },
|
||||||
error: (error: Error) => {
|
// error: (error: Error) => {
|
||||||
console.error("CSV parsing error:", error);
|
// console.error("CSV parsing error:", error);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
data,
|
// data,
|
||||||
headers,
|
// headers,
|
||||||
};
|
// };
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
console.error("Failed to parse CSV:", error);
|
// console.error("Failed to parse CSV:", error);
|
||||||
return { data: [], headers: [] };
|
// return { data: [], headers: [] };
|
||||||
}
|
// }
|
||||||
}, [content]);
|
// }, [content]);
|
||||||
|
|
||||||
// Filter data based on search term
|
// // Filter data based on search term
|
||||||
const filteredData = useMemo(() => {
|
// const filteredData = useMemo(() => {
|
||||||
if (!searchTerm.trim()) return parsedData.data;
|
// if (!searchTerm.trim()) return parsedData.data;
|
||||||
|
|
||||||
const lowerCaseSearchTerm = searchTerm.toLowerCase();
|
// const lowerCaseSearchTerm = searchTerm.toLowerCase();
|
||||||
return parsedData.data.filter((row: Record<string, string>) => {
|
// return parsedData.data.filter((row: Record<string, string>) => {
|
||||||
return Object.values(row).some((value: any) => {
|
// return Object.values(row).some((value: any) => {
|
||||||
if (value === null || value === undefined) return false;
|
// if (value === null || value === undefined) return false;
|
||||||
return String(value).toLowerCase().includes(lowerCaseSearchTerm);
|
// return String(value).toLowerCase().includes(lowerCaseSearchTerm);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
}, [parsedData.data, searchTerm]);
|
// }, [parsedData.data, searchTerm]);
|
||||||
|
|
||||||
// Paginate data
|
// // Paginate data
|
||||||
const paginatedData = useMemo(() => {
|
// const paginatedData = useMemo(() => {
|
||||||
const startIndex = (currentPage - 1) * rowsPerPage;
|
// const startIndex = (currentPage - 1) * rowsPerPage;
|
||||||
return filteredData.slice(startIndex, startIndex + rowsPerPage);
|
// return filteredData.slice(startIndex, startIndex + rowsPerPage);
|
||||||
}, [filteredData, currentPage, rowsPerPage]);
|
// }, [filteredData, currentPage, rowsPerPage]);
|
||||||
|
|
||||||
// Calculate total pages
|
// // Calculate total pages
|
||||||
const totalPages = Math.max(1, Math.ceil(filteredData.length / rowsPerPage));
|
// const totalPages = Math.max(1, Math.ceil(filteredData.length / rowsPerPage));
|
||||||
|
|
||||||
// Reset to first page when search changes
|
// // Reset to first page when search changes
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
setCurrentPage(1);
|
// setCurrentPage(1);
|
||||||
}, [searchTerm]);
|
// }, [searchTerm]);
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<div className={cn("flex flex-col h-full w-full", className)}>
|
// <div className={cn("flex flex-col h-full w-full", className)}>
|
||||||
{/* Search and pagination controls */}
|
// {/* Search and pagination controls */}
|
||||||
<div className="flex items-center justify-between p-4 border-b">
|
// <div className="flex items-center justify-between p-4 border-b">
|
||||||
<div className="relative w-full max-w-sm">
|
// <div className="relative w-full max-w-sm">
|
||||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
// <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||||
<Input
|
// <Input
|
||||||
type="text"
|
// type="text"
|
||||||
placeholder="Search..."
|
// placeholder="Search..."
|
||||||
value={searchTerm}
|
// value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
// onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
className="pl-9"
|
// className="pl-9"
|
||||||
/>
|
// />
|
||||||
</div>
|
// </div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 ml-4">
|
// <div className="flex items-center gap-2 ml-4">
|
||||||
<Button
|
// <Button
|
||||||
variant="outline"
|
// variant="outline"
|
||||||
size="icon"
|
// size="icon"
|
||||||
onClick={() => setCurrentPage(Math.max(1, currentPage - 1))}
|
// onClick={() => setCurrentPage(Math.max(1, currentPage - 1))}
|
||||||
disabled={currentPage === 1}
|
// disabled={currentPage === 1}
|
||||||
>
|
// >
|
||||||
<ChevronLeft className="h-4 w-4" />
|
// <ChevronLeft className="h-4 w-4" />
|
||||||
</Button>
|
// </Button>
|
||||||
|
|
||||||
<span className="text-sm text-muted-foreground min-w-[100px] text-center">
|
// <span className="text-sm text-muted-foreground min-w-[100px] text-center">
|
||||||
Page {currentPage} of {totalPages}
|
// Page {currentPage} of {totalPages}
|
||||||
</span>
|
// </span>
|
||||||
|
|
||||||
<Button
|
// <Button
|
||||||
variant="outline"
|
// variant="outline"
|
||||||
size="icon"
|
// size="icon"
|
||||||
onClick={() => setCurrentPage(Math.min(totalPages, currentPage + 1))}
|
// onClick={() => setCurrentPage(Math.min(totalPages, currentPage + 1))}
|
||||||
disabled={currentPage === totalPages}
|
// disabled={currentPage === totalPages}
|
||||||
>
|
// >
|
||||||
<ChevronRight className="h-4 w-4" />
|
// <ChevronRight className="h-4 w-4" />
|
||||||
</Button>
|
// </Button>
|
||||||
</div>
|
// </div>
|
||||||
</div>
|
// </div>
|
||||||
|
|
||||||
{/* Table */}
|
// {/* Table */}
|
||||||
<ScrollArea className="flex-1 w-full relative">
|
// <ScrollArea className="flex-1 w-full relative">
|
||||||
<div className="min-w-full">
|
// <div className="min-w-full">
|
||||||
<Table>
|
// <Table>
|
||||||
<TableHeader className="sticky top-0 bg-background z-10">
|
// <TableHeader className="sticky top-0 bg-background z-10">
|
||||||
<TableRow>
|
// <TableRow>
|
||||||
{parsedData.headers.map((header, index) => (
|
// {parsedData.headers.map((header, index) => (
|
||||||
<TableHead key={index} className="whitespace-nowrap">
|
// <TableHead key={index} className="whitespace-nowrap">
|
||||||
{header}
|
// {header}
|
||||||
</TableHead>
|
// </TableHead>
|
||||||
))}
|
// ))}
|
||||||
</TableRow>
|
// </TableRow>
|
||||||
</TableHeader>
|
// </TableHeader>
|
||||||
<TableBody>
|
// <TableBody>
|
||||||
{paginatedData.length > 0 ? (
|
// {paginatedData.length > 0 ? (
|
||||||
paginatedData.map((row, rowIndex) => (
|
// paginatedData.map((row, rowIndex) => (
|
||||||
<TableRow key={rowIndex}>
|
// <TableRow key={rowIndex}>
|
||||||
{parsedData.headers.map((header, cellIndex) => (
|
// {parsedData.headers.map((header, cellIndex) => (
|
||||||
<TableCell key={cellIndex} className={cellIndex === 0 ? "font-medium" : ""}>
|
// <TableCell key={cellIndex} className={cellIndex === 0 ? "font-medium" : ""}>
|
||||||
{row[header] || ""}
|
// {row[header] || ""}
|
||||||
</TableCell>
|
// </TableCell>
|
||||||
))}
|
// ))}
|
||||||
</TableRow>
|
// </TableRow>
|
||||||
))
|
// ))
|
||||||
) : (
|
// ) : (
|
||||||
<TableRow>
|
// <TableRow>
|
||||||
<TableCell
|
// <TableCell
|
||||||
colSpan={parsedData.headers.length || 1}
|
// colSpan={parsedData.headers.length || 1}
|
||||||
className="h-24 text-center"
|
// className="h-24 text-center"
|
||||||
>
|
// >
|
||||||
{searchTerm ? "No results found." : "No data available."}
|
// {searchTerm ? "No results found." : "No data available."}
|
||||||
</TableCell>
|
// </TableCell>
|
||||||
</TableRow>
|
// </TableRow>
|
||||||
)}
|
// )}
|
||||||
</TableBody>
|
// </TableBody>
|
||||||
</Table>
|
// </Table>
|
||||||
</div>
|
// </div>
|
||||||
</ScrollArea>
|
// </ScrollArea>
|
||||||
</div>
|
// </div>
|
||||||
);
|
// );
|
||||||
}
|
// }
|
Loading…
Reference in New Issue