Prompt to task UI (#455)
This commit is contained in:
@@ -12,6 +12,7 @@ import { TaskActions } from "./routes/tasks/detail/TaskActions";
|
|||||||
import { TaskRecording } from "./routes/tasks/detail/TaskRecording";
|
import { TaskRecording } from "./routes/tasks/detail/TaskRecording";
|
||||||
import { TaskParameters } from "./routes/tasks/detail/TaskParameters";
|
import { TaskParameters } from "./routes/tasks/detail/TaskParameters";
|
||||||
import { StepArtifactsLayout } from "./routes/tasks/detail/StepArtifactsLayout";
|
import { StepArtifactsLayout } from "./routes/tasks/detail/StepArtifactsLayout";
|
||||||
|
import { CreateNewTaskFromPrompt } from "./routes/tasks/create/CreateNewTaskFromPrompt";
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
@@ -66,6 +67,10 @@ const router = createBrowserRouter([
|
|||||||
index: true,
|
index: true,
|
||||||
element: <TaskTemplates />,
|
element: <TaskTemplates />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "sk-prompt",
|
||||||
|
element: <CreateNewTaskFromPrompt />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: ":template",
|
path: ":template",
|
||||||
element: <CreateNewTaskFormPage />,
|
element: <CreateNewTaskFormPage />,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
import { getClient } from "@/api/AxiosClient";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { CreateNewTaskForm } from "./CreateNewTaskForm";
|
|
||||||
import { getSampleForInitialFormValues } from "../data/sampleTaskData";
|
import { getSampleForInitialFormValues } from "../data/sampleTaskData";
|
||||||
import { SampleCase, sampleCases } from "../types";
|
import { SampleCase, sampleCases } from "../types";
|
||||||
|
import { CreateNewTaskForm } from "./CreateNewTaskForm";
|
||||||
import { SavedTaskForm } from "./SavedTaskForm";
|
import { SavedTaskForm } from "./SavedTaskForm";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
|
||||||
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
|
||||||
import { getClient } from "@/api/AxiosClient";
|
|
||||||
|
|
||||||
function CreateNewTaskFormPage() {
|
function CreateNewTaskFormPage() {
|
||||||
const { template } = useParams();
|
const { template } = useParams();
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
import { CreateNewTaskForm } from "./CreateNewTaskForm";
|
||||||
|
import { MagicWandIcon } from "@radix-ui/react-icons";
|
||||||
|
|
||||||
|
function CreateNewTaskFromPrompt() {
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
const state = location.state.data;
|
||||||
|
return (
|
||||||
|
<section className="space-y-8">
|
||||||
|
<header className="flex flex-col gap-4">
|
||||||
|
<div className="flex gap-4 items-center">
|
||||||
|
<MagicWandIcon className="w-6 h-6" />
|
||||||
|
<h1 className="text-3xl font-bold">Create New Task</h1>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Prompt: <span>{state.user_prompt}</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Below are the parameters we generated automatically. You can go ahead
|
||||||
|
and create the task if everything looks correct.
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
<CreateNewTaskForm
|
||||||
|
initialValues={{
|
||||||
|
url: state.url,
|
||||||
|
navigationGoal: state.navigation_goal,
|
||||||
|
dataExtractionGoal: state.data_extraction_goal,
|
||||||
|
extractedInformationSchema: JSON.stringify(
|
||||||
|
state.extracted_information_schema,
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
navigationPayload: JSON.stringify(state.navigation_payload, null, 2),
|
||||||
|
webhookCallbackUrl: "",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { CreateNewTaskFromPrompt };
|
||||||
@@ -10,6 +10,19 @@ import { Separator } from "@/components/ui/separator";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { SavedTasks } from "./SavedTasks";
|
import { SavedTasks } from "./SavedTasks";
|
||||||
import { getSample } from "../data/sampleTaskData";
|
import { getSample } from "../data/sampleTaskData";
|
||||||
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { PaperPlaneIcon, ReloadIcon } from "@radix-ui/react-icons";
|
||||||
|
import { useMutation } from "@tanstack/react-query";
|
||||||
|
import { useCredentialGetter } from "@/hooks/useCredentialGetter";
|
||||||
|
import { getClient } from "@/api/AxiosClient";
|
||||||
|
import { AxiosError } from "axios";
|
||||||
|
import { toast } from "@/components/ui/use-toast";
|
||||||
|
|
||||||
|
const examplePrompts = [
|
||||||
|
"What is the top post on hackernews?",
|
||||||
|
"Navigate to Google Finance and search for AAPL",
|
||||||
|
];
|
||||||
|
|
||||||
const templateSamples: {
|
const templateSamples: {
|
||||||
[key in SampleCase]: {
|
[key in SampleCase]: {
|
||||||
@@ -41,9 +54,74 @@ const templateSamples: {
|
|||||||
|
|
||||||
function TaskTemplates() {
|
function TaskTemplates() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [prompt, setPrompt] = useState<string>("");
|
||||||
|
const credentialGetter = useCredentialGetter();
|
||||||
|
|
||||||
|
const getTaskFromPromptMutation = useMutation({
|
||||||
|
mutationFn: async (prompt: string) => {
|
||||||
|
const client = await getClient(credentialGetter);
|
||||||
|
return client
|
||||||
|
.post("/generate/task", { prompt })
|
||||||
|
.then((response) => response.data);
|
||||||
|
},
|
||||||
|
onSuccess: (response) => {
|
||||||
|
navigate("/create/sk-prompt", { state: { data: response } });
|
||||||
|
},
|
||||||
|
onError: (error: AxiosError) => {
|
||||||
|
toast({
|
||||||
|
variant: "destructive",
|
||||||
|
title: "Error creating task from prompt",
|
||||||
|
description: error.message,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<section className="py-4">
|
||||||
|
<header>
|
||||||
|
<h1 className="text-3xl mb-2">Try a prompt</h1>
|
||||||
|
</header>
|
||||||
|
<p className="text-sm">
|
||||||
|
We will generate a task for you automatically.
|
||||||
|
</p>
|
||||||
|
<Separator className="mt-2 mb-8" />
|
||||||
|
<div className="flex border rounded-xl items-center pr-4 max-w-xl mx-auto">
|
||||||
|
<Textarea
|
||||||
|
className="rounded-xl resize-none border-transparent hover:border-transparent focus-visible:ring-0 p-2 font-mono text-sm"
|
||||||
|
value={prompt}
|
||||||
|
onChange={(e) => setPrompt(e.target.value)}
|
||||||
|
placeholder="Enter your prompt..."
|
||||||
|
/>
|
||||||
|
<div className="h-full">
|
||||||
|
{getTaskFromPromptMutation.isPending ? (
|
||||||
|
<ReloadIcon className="w-6 h-6 animate-spin" />
|
||||||
|
) : (
|
||||||
|
<PaperPlaneIcon
|
||||||
|
className="w-6 h-6 cursor-pointer"
|
||||||
|
onClick={() => {
|
||||||
|
getTaskFromPromptMutation.mutate(prompt);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-wrap gap-4 mt-4 justify-center">
|
||||||
|
{examplePrompts.map((examplePrompt) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={examplePrompt}
|
||||||
|
className="p-2 border rounded-xl cursor-pointer text-muted-foreground text-sm"
|
||||||
|
onClick={() => {
|
||||||
|
setPrompt(examplePrompt);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{examplePrompt}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
<section className="py-4">
|
<section className="py-4">
|
||||||
<header>
|
<header>
|
||||||
<h1 className="text-3xl">Your Templates</h1>
|
<h1 className="text-3xl">Your Templates</h1>
|
||||||
|
|||||||
Reference in New Issue
Block a user