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";