Skip to content

Commit

Permalink
Fix results table display (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
eyurtsev authored Mar 21, 2024
1 parent 7eff8a4 commit 7e89376
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 14 deletions.
35 changes: 33 additions & 2 deletions frontend/app/components/Playground.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -87,7 +99,26 @@ export const Playground = (props: PlaygroundProps) => {
</form>
</div>
<div className="m-auto">
<ResultsTable data={data} isPending={isPending} />
<Tabs>
<TabList>
<Tab>Table</Tab>
<Tab>JSON</Tab>
</TabList>
<TabPanels>
<TabPanel>
<ResultsTable data={data} isPending={isPending} />
</TabPanel>
<TabPanel>
<Text className="mt-1 mb-5">
This shows the raw JSON Schema that describes what information
the extractor will be extracting from the content.
</Text>
<SyntaxHighlighter language="json" style={docco}>
{JSON.stringify(data, null, 2)}
</SyntaxHighlighter>
</TabPanel>
</TabPanels>
</Tabs>
</div>
</div>
);
Expand Down
56 changes: 46 additions & 10 deletions frontend/app/components/ResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,63 @@ import {
Tr,
} from "@chakra-ui/react";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function getColumns(records: Array<Record<string, any>>): Array<any> {
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null;
}

function getColumns(records: unknown[]): Array<string> {
// Create a set to store unique keys
const uniqueKeys = new Set();
const uniqueKeys = new Set<string>();

// 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);
}
});
});

// Convert the set back into an array and return it
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<Record<string, any>> } | 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 (
<Spinner
Expand All @@ -52,6 +79,9 @@ export const ResultsTable = ({
);
}

const actualData = data?.data;
const columns = actualData ? getColumns(actualData) : [];

return (
<div>
<TableContainer>
Expand All @@ -69,7 +99,13 @@ export const ResultsTable = ({
return (
<Tr key={index}>
{columns.map((column, idx) => (
<Td key={`table-data-${idx}`}>{row[column]}</Td>
// Check if the row has the column,
// if not, display an empty cell
<Td key={`table-cell-${idx}`}>
{isRecord(row) && column in row
? getDisplayValue(row[column])
: ""}
</Td>
))}
</Tr>
);
Expand Down
7 changes: 5 additions & 2 deletions frontend/app/utils/api.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down

0 comments on commit 7e89376

Please sign in to comment.