diff --git a/frontend/app/components/ExampleEditor.tsx b/frontend/app/components/ExampleEditor.tsx
deleted file mode 100644
index 3925363..0000000
--- a/frontend/app/components/ExampleEditor.tsx
+++ /dev/null
@@ -1,183 +0,0 @@
-"use client";
-
-import {
- AbsoluteCenter,
- Box,
- Button,
- Divider,
- IconButton,
- Table,
- TableCaption,
- Tbody,
- Td,
- Text,
- Th,
- Thead,
- Tr,
-} from "@chakra-ui/react";
-
-import { TrashIcon } from "@heroicons/react/24/outline";
-import Form from "@rjsf/chakra-ui";
-import validator from "@rjsf/validator-ajv8";
-import { docco } from "react-syntax-highlighter/dist/esm/styles/hljs";
-
-import SyntaxHighlighter from "react-syntax-highlighter";
-import {
- useCreateExample,
- useDeleteExample,
- useGetExtractor,
- useListExamples,
-} from "../utils/api";
-
-type ExtractorProps = {
- extractorId: string;
- isShared: boolean;
-};
-
-/**
- * Component to view and manage an extractor.
- */
-const Examples = ({ extractorId }: { extractorId: string }) => {
- const listExamplesQuery = useListExamples({
- extractor_id: extractorId,
- limit: 10,
- offset: 0, // Hard code pagination for now
- });
- const useDeleteMutation = useDeleteExample();
- if (listExamplesQuery.isLoading) {
- return
Loading...
;
- }
- if (listExamplesQuery.isError) {
- return (
- Unable to load examples for extractor with ID: {extractorId}
- );
- }
- const data = listExamplesQuery.data;
- return (
-
- {data && data.length === 0 ? (
-
Use the form below to add examples to the extractor
- ) : (
-
-
- View and Delete Examples
-
-
-
- Content
- Output
- Action
-
-
-
- {data &&
- data.map((example) => (
-
- {example.content}
-
-
- {JSON.stringify(example.output, null, 2)}
-
-
-
-
- useDeleteMutation.mutate({ uuid: example.uuid })
- }
- variant={"outline"}
- isLoading={useDeleteMutation.isPending}
- colorScheme="red"
- aria-label="Delete example"
- icon={ }
- />
-
-
- ))}
-
-
- )}
-
- );
-};
-
-export const ExampleEditor = ({ extractorId, isShared }: ExtractorProps) => {
- const { data, isLoading, isError } = useGetExtractor(extractorId, isShared);
- const createExampleMutation = useCreateExample();
- if (isLoading) {
- return Loading...
;
- }
- if (isError) {
- return Unable to load extractor with ID: {extractorId}
;
- }
-
- if (data === undefined) {
- throw new Error("Data is undefined");
- }
-
- const newSchema = {
- type: "object",
- properties: {
- content: {
- type: "string",
- title: "Content",
- },
- output: {
- // Array of data.schema
- type: "array",
- items: {
- ...data.schema,
- title: undefined,
- description: undefined,
- },
- },
- },
- required: ["content"],
- };
-
- const UISchema = {
- content: {
- "ui:autoFocus": true,
- "ui:placeholder": "Enter contact to extract",
- "ui:widget": "textarea",
- "ui:description": "Enter the text to extract information from",
- },
- output: {
- "ui:autoFocus": false,
- "ui:title": "Outputs",
- },
- };
-
- const handleAddExample = (
- /* eslint-disable @typescript-eslint/no-explicit-any */
- formData: any,
- ) => {
- createExampleMutation.mutate({
- extractor_id: extractorId,
- content: formData.formData.content,
- output: formData.formData.output,
- });
- };
-
- return (
-
- );
-};
diff --git a/frontend/app/components/Extractor.tsx b/frontend/app/components/Extractor.tsx
new file mode 100644
index 0000000..4b0c84e
--- /dev/null
+++ b/frontend/app/components/Extractor.tsx
@@ -0,0 +1,62 @@
+"use client";
+
+import {
+ Tab,
+ TabList,
+ TabPanel,
+ TabPanels,
+ Tabs,
+ Text,
+} from "@chakra-ui/react";
+import Form from "@rjsf/chakra-ui";
+import validator from "@rjsf/validator-ajv8";
+import { docco } from "react-syntax-highlighter/dist/esm/styles/hljs";
+
+import SyntaxHighlighter from "react-syntax-highlighter";
+import { useGetExtractor } from "../utils/api";
+
+type ExtractorProps = {
+ extractorId: string;
+ isShared: boolean;
+};
+
+export const Extractor = ({ extractorId, isShared }: ExtractorProps) => {
+ const { data, isLoading, isError } = useGetExtractor(extractorId, isShared);
+ if (isLoading) {
+ return Loading...
;
+ }
+ if (isError) {
+ return Unable to load extractor with ID: {extractorId}
;
+ }
+
+ if (data === undefined) {
+ throw new Error("Data is undefined");
+ }
+
+ return (
+
+
+
+ Form
+ Code
+
+
+
+
+
+
+
+ This shows the raw JSON Schema that describes what information the
+ extractor will be extracting from the content.
+
+
+ {JSON.stringify(data.schema, null, 2)}
+
+
+
+
+
+ );
+};
diff --git a/frontend/app/components/Playground.tsx b/frontend/app/components/Playground.tsx
index c0e7e56..595bf71 100644
--- a/frontend/app/components/Playground.tsx
+++ b/frontend/app/components/Playground.tsx
@@ -1,33 +1,29 @@
"use client";
import {
- AbsoluteCenter,
- Badge,
- Box,
Button,
- Divider,
- FormControl,
- FormLabel,
- HStack,
Heading,
- Radio,
- RadioGroup,
- Spinner,
Tab,
+ Box,
+ Divider,
+ AbsoluteCenter,
TabList,
TabPanel,
TabPanels,
Tabs,
Text,
Textarea,
+ FormControl,
+ FormLabel,
+ HStack,
+ Radio,
+ RadioGroup,
} from "@chakra-ui/react";
-import Form from "@rjsf/chakra-ui";
-import validator from "@rjsf/validator-ajv8";
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, useConfiguration, useGetExtractor } from "../utils/api";
-import { ExampleEditor } from "./ExampleEditor";
+import { runExtraction, useConfiguration } from "../utils/api";
+import { Extractor } from "./Extractor";
import { ResultsTable } from "./ResultsTable";
interface PlaygroundProps {
@@ -48,8 +44,6 @@ export const Playground = (props: PlaygroundProps) => {
mutationFn: runExtraction,
});
- const extractorQuery = useGetExtractor(extractorId, isShared);
-
const requestServerConfig = useConfiguration();
const [isDisabled, setIsDisabled] = React.useState(true);
@@ -103,163 +97,97 @@ export const Playground = (props: PlaygroundProps) => {
setIsDisabled(false);
};
- if (extractorQuery.isLoading) {
- return (
-
- );
- }
-
- if (extractorQuery.isError) {
- return Unable to load extractor with ID: {extractorId}
;
- }
-
- if (extractorQuery.data === undefined) {
- throw new Error("Data is undefined");
- }
-
- // Project the schema without the title, name, description
- const cleanedSchema = {
- ...extractorQuery.data.schema,
- title: undefined,
- description: undefined,
- };
-
return (
-
- {extractorQuery.data?.name}
- {isShared && (
-
- SHARED
-
+ {isShared && Using a shared exractor }
+
+
+
+ Extract
+
+
-
- {extractorQuery.data?.description}
-
-
+
+
+
+ OR
+
+
+
+
+ Run
+
+
+
+
+ {data?.content_too_long && (
+
+ The content was too long to be processed. Extraction was run on a
+ truncated version of the content.
+
+ )}
+
- Extract
- JSON Schema
- Examples
+ Table
+ JSON
-
-
-
-
- {data?.content_too_long && (
-
- The content was too long to be processed. Extraction was run
- on a truncated version of the content.
-
- )}
-
-
- Table
- JSON
-
-
-
-
-
-
-
- Shows the output from the extractor in JSON format.
-
-
- {JSON.stringify(data, null, 2)}
-
-
-
-
-
+
- The raw JSON schema for the extractor.
+ Shows the output from the extractor in JSON format.
- {JSON.stringify(extractorQuery.data.schema, null, 2)}
+ {JSON.stringify(data, null, 2)}
-
-
-
diff --git a/frontend/app/utils/api.tsx b/frontend/app/utils/api.tsx
index 6945f66..4688e1f 100644
--- a/frontend/app/utils/api.tsx
+++ b/frontend/app/utils/api.tsx
@@ -181,96 +181,3 @@ export const useCreateExtractor = ({
},
});
};
-
-type CreateExampleRequest = {
- extractor_id: string;
- content: string;
- // Any can be any JSON serializable object
- /* eslint-disable @typescript-eslint/no-explicit-any */
- output: any[];
-};
-
-type CreateExampleResponse = {
- uuid: string;
-};
-
-const createExample: MutationFunction<
- CreateExampleResponse,
- CreateExampleRequest
-> = async (example) => {
- const baseUrl = getBaseApiUrl();
- const response = await axiosClient.post(`${baseUrl}/examples`, example);
- return response.data;
-};
-
-export const useCreateExample = () => {
- const queryClient = useQueryClient();
- return useMutation({
- mutationFn: createExample,
- onSuccess: () => {
- // TDOO: invalidate only for the extractor ID asscoiated with the example
- // that was deleted.
- queryClient.invalidateQueries({ queryKey: ["listExamples"] });
- },
- });
-};
-type DeleteExampleParams = {
- uuid: string;
-};
-
-const deleteExample = async ({ uuid }: DeleteExampleParams): Promise
=> {
- const baseUrl: string = getBaseApiUrl();
- await axiosClient.delete(`${baseUrl}/examples/${uuid}`);
-};
-
-export const useDeleteExample = () => {
- const queryClient = useQueryClient();
- return useMutation({
- mutationFn: deleteExample,
- onSuccess: () => {
- // TDOO: invalidate only for the extractor ID asscoiated with the example
- // that was deleted.
- queryClient.invalidateQueries({ queryKey: ["listExamples"] });
- },
- });
-};
-
-type Example = {
- uuid: string;
- content: string;
- output: any[];
-};
-
-type ListExamplesParams = {
- extractor_id: string;
- limit: number;
- offset: number;
-};
-
-const fetchExamples = async ({
- queryKey,
-}: {
- queryKey: [string, string, number, number];
-}): Promise => {
- const [, extractor_id, limit = 10, offset = 0] = queryKey;
- const baseUrl = getBaseApiUrl();
- const queryParams: string = new URLSearchParams({
- extractor_id,
- limit: limit.toString(),
- offset: offset.toString(),
- }).toString();
- const response = await axiosClient.get(`${baseUrl}/examples?${queryParams}`);
- return response.data;
-};
-
-export const useListExamples = (params: ListExamplesParams) => {
- return useQuery({
- queryKey: [
- "listExamples",
- params.extractor_id,
- params.limit,
- params.offset,
- ],
- queryFn: fetchExamples,
- });
-};