diff --git a/frontend/app/components/Playground.tsx b/frontend/app/components/Playground.tsx index f0d83cd..466ca9e 100644 --- a/frontend/app/components/Playground.tsx +++ b/frontend/app/components/Playground.tsx @@ -1,8 +1,20 @@ "use client"; -import { Button, Textarea, Heading } from "@chakra-ui/react"; +import { + Button, + Textarea, + Heading, + Tab, + Tabs, + TabList, + TabPanel, + TabPanels, + Text, +} from "@chakra-ui/react"; import { useMutation } from "@tanstack/react-query"; import React from "react"; +import SyntaxHighlighter from "react-syntax-highlighter"; +import { docco } from "react-syntax-highlighter/dist/esm/styles/hljs"; import { runExtraction } from "../utils/api"; import { Extractor } from "./Extractor"; import { ResultsTable } from "./ResultsTable"; @@ -87,7 +99,26 @@ export const Playground = (props: PlaygroundProps) => {
- + + + Table + JSON + + + + + + + + This shows the raw JSON Schema that describes what information + the extractor will be extracting from the content. + + + {JSON.stringify(data, null, 2)} + + + +
); diff --git a/frontend/app/components/ResultsTable.tsx b/frontend/app/components/ResultsTable.tsx index 185ef42..83597ef 100644 --- a/frontend/app/components/ResultsTable.tsx +++ b/frontend/app/components/ResultsTable.tsx @@ -10,16 +10,24 @@ import { Tr, } from "@chakra-ui/react"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function getColumns(records: Array>): Array { +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null; +} + +function getColumns(records: unknown[]): Array { // Create a set to store unique keys - const uniqueKeys = new Set(); + const uniqueKeys = new Set(); // Iterate over each record in the list records.forEach((record) => { // For each key in the current record, add it to the set + if (!isRecord(record)) { + return; + } Object.keys(record).forEach((key) => { - uniqueKeys.add(key); + if (typeof key === "string") { + uniqueKeys.add(key); + } }); }); @@ -27,19 +35,38 @@ function getColumns(records: Array>): Array { return Array.from(uniqueKeys); } +/* + * This function takes a value and returns a string representation of it. + * If the value is an array, it will join the elements with a comma and space. + * If the value is an object, it will create an array of strings representing + * each key-value pair, then join them with a comma and space. + * Otherwise, it will return the string representation of the value. + * @param value - The value to display + * @returns The string representation of the value + */ +function getDisplayValue(value: unknown): string { + if (Array.isArray(value)) { + return value.map(getDisplayValue).join(", "); + } + if (isRecord(value)) { + // Creating an array of strings representing each key-value pair, + // then joining them with a comma and space. + return Object.entries(value) + .map(([key, val]) => `${key}: ${getDisplayValue(val)}`) + .join(", "); + } + return String(value); +} + export const ResultsTable = ({ data, isPending, }: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - data: { data: Array> } | undefined; + data: { data: unknown[] } | undefined; isPending: boolean; }) => { // scan all the results to determine the columns // then display the results in a table - const actualData = data?.data; - const columns = actualData ? getColumns(actualData) : []; - if (isPending) { return ( @@ -69,7 +99,13 @@ export const ResultsTable = ({ return ( {columns.map((column, idx) => ( - {row[column]} + // Check if the row has the column, + // if not, display an empty cell + + {isRecord(row) && column in row + ? getDisplayValue(row[column]) + : ""} + ))} ); diff --git a/frontend/app/utils/api.tsx b/frontend/app/utils/api.tsx index dee109c..7c837f6 100644 --- a/frontend/app/utils/api.tsx +++ b/frontend/app/utils/api.tsx @@ -74,9 +74,12 @@ type ExtractionRequest = { file?: File; }; +type ExtractionResponse = { + data: unknown[]; +}; + export const runExtraction: MutationFunction< - // eslint-disable-next-line @typescript-eslint/no-explicit-any - any, + ExtractionResponse, [ExtractionRequest, boolean] > = async ([extractionRequest, isShared]) => { const endpoint = isShared ? "extract/shared" : "extract";