Skip to content

Commit

Permalink
[OPIK-348]: add edit to the prompt table;
Browse files Browse the repository at this point in the history
  • Loading branch information
Sasha committed Nov 6, 2024
1 parent 528b63d commit 513161e
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 31 deletions.
47 changes: 47 additions & 0 deletions apps/opik-frontend/src/api/prompts/usePromptUpdateMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
import get from "lodash/get";

import api, { PROMPTS_REST_ENDPOINT } from "@/api/api";
import { useToast } from "@/components/ui/use-toast";
import { Prompt } from "@/types/prompts";

type UsePromptUpdateMutationParams = {
prompt: Partial<Prompt>;
};

const usePromptUpdateMutation = () => {
const queryClient = useQueryClient();
const { toast } = useToast();

return useMutation({
mutationFn: async ({ prompt }: UsePromptUpdateMutationParams) => {
const { id: promptId, ...restPrompt } = prompt;

const { data } = await api.put(`${PROMPTS_REST_ENDPOINT}${promptId}`, {
...restPrompt,
});

return data;
},

onError: (error: AxiosError) => {
const message = get(
error,
["response", "data", "message"],
error.message,
);

toast({
title: "Error",
description: message,
variant: "destructive",
});
},
onSettled: () => {
return queryClient.invalidateQueries({ queryKey: ["prompts"] });
},
});
};

export default usePromptUpdateMutation;
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,67 @@ import {
AccordionTrigger,
Accordion,
} from "@/components/ui/accordion";
import usePromptUpdateMutation from "@/api/prompts/usePromptUpdateMutation";

// ALEX REMOVE ONPROMPTCREATED
type AddPromptDialogProps = {
open: boolean;
setOpen: (open: boolean) => void;
onPromptCreated?: (prompt: Prompt) => void;
prompt?: Prompt;
};

const AddPromptDialog: React.FunctionComponent<AddPromptDialogProps> = ({
const AddEditPromptDialog: React.FunctionComponent<AddPromptDialogProps> = ({
open,
setOpen,
onPromptCreated,
prompt: defaultPrompt,
}) => {
const workspaceName = useAppStore((state) => state.activeWorkspaceName);

Check failure on line 39 in apps/opik-frontend/src/components/pages/PromptsPage/AddEditPromptDialog.tsx

View workflow job for this annotation

GitHub Actions / lint

'workspaceName' is assigned a value but never used

const [name, setName] = useState(defaultPrompt?.name || "");
const [template, setTemplate] = useState("");
const [description, setDescription] = useState(
defaultPrompt?.description || "",
);

const promptCreateMutation = usePromptCreateMutation();
const [name, setName] = useState("");
const [prompt, setPrompt] = useState("");
const [description, setDescription] = useState("");
const promptUpdateMutation = usePromptUpdateMutation();

const isValid = Boolean(name.length && prompt.length);
const isEdit = !!defaultPrompt;
const isValid = Boolean(name.length && (isEdit || template.length));

const createPrompt = useCallback(() => {
promptCreateMutation.mutate(
{
prompt: {
name,
template: prompt,
template,
...(description ? { description } : {}),
},
},
// ALEX
{ onSuccess: onPromptCreated },
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [name, description, workspaceName, prompt, onPromptCreated]);
}, [name, description, template, onPromptCreated]);

const editPrompt = useCallback(() => {
promptUpdateMutation.mutate({
prompt: {
id: defaultPrompt?.id,
name,
...(description ? { description } : {}),
},
});
}, [name, description, defaultPrompt?.id]);

const onActionClick = () => {
if (isEdit) {
return editPrompt();
}

createPrompt();
};

return (
<Dialog open={open} onOpenChange={setOpen}>
Expand All @@ -69,20 +97,22 @@ const AddPromptDialog: React.FunctionComponent<AddPromptDialogProps> = ({
onChange={(event) => setName(event.target.value)}
/>
</div>
<div className="flex flex-col gap-2 pb-4">
<Label htmlFor="prompt">Prompt</Label>
<Textarea
id="prompt"
className="comet-code"
placeholder="Prompt"
value={prompt}
onChange={(event) => setPrompt(event.target.value)}
/>
<p className="comet-body-xs text-light-slate">
You can specify variables using the &quot;mustache&quot; syntax:{" "}
{"{{variable}}"}.
</p>
</div>
{!isEdit && (
<div className="flex flex-col gap-2 pb-4">
<Label htmlFor="template">Prompt</Label>
<Textarea
id="template"
className="comet-code"
placeholder="Prompt"
value={template}
onChange={(event) => setTemplate(event.target.value)}
/>
<p className="comet-body-xs text-light-slate">
You can specify variables using the &quot;mustache&quot; syntax:{" "}
{"{{variable}}"}.
</p>
</div>
)}
<div className="flex flex-col gap-2 border-t border-border pb-4">
<Accordion type="multiple">
<AccordionItem value="description">
Expand All @@ -104,8 +134,8 @@ const AddPromptDialog: React.FunctionComponent<AddPromptDialogProps> = ({
<Button variant="outline">Cancel</Button>
</DialogClose>
<DialogClose asChild>
<Button type="submit" disabled={!isValid} onClick={createPrompt}>
Create prompt
<Button type="submit" disabled={!isValid} onClick={onActionClick}>
{isEdit ? "Edit prompt" : "Create prompt"}
</Button>
</DialogClose>
</DialogFooter>
Expand All @@ -114,4 +144,4 @@ const AddPromptDialog: React.FunctionComponent<AddPromptDialogProps> = ({
);
};

export default AddPromptDialog;
export default AddEditPromptDialog;
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { MoreHorizontal, Trash } from "lucide-react";
import { MoreHorizontal, Pencil, Trash } from "lucide-react";
import React, { useCallback, useRef, useState } from "react";
import { CellContext } from "@tanstack/react-table";
import ConfirmDialog from "@/components/shared/ConfirmDialog/ConfirmDialog";
import { Prompt } from "@/types/prompts";
import usePromptDeleteMutation from "@/api/prompts/usePromptDeleteMutation";
import AddEditPromptDialog from "@/components/pages/PromptsPage/AddEditPromptDialog";

const EDIT_KEY = 1;
const DELETE_KEY = 2;

export const PromptRowActionsCell: React.FunctionComponent<
CellContext<Prompt, unknown>
> = ({ row }) => {
const resetKeyRef = useRef(0);
const prompt = row.original;
const [open, setOpen] = useState<boolean>(false);
const [open, setOpen] = useState<number | boolean>(false);

const promptDeleteMutation = usePromptDeleteMutation();

Expand All @@ -33,9 +37,16 @@ export const PromptRowActionsCell: React.FunctionComponent<
className="flex size-full items-center justify-end"
onClick={(e) => e.stopPropagation()}
>
<AddEditPromptDialog
key={`edit-${resetKeyRef.current}`}
open={open === 1}
setOpen={setOpen}
prompt={prompt}
/>

<ConfirmDialog
key={`delete-${resetKeyRef.current}`}
open={open}
open={open === 2}
setOpen={setOpen}
onConfirm={deletePromptHandler}
title={`Delete ${prompt.name}`}
Expand All @@ -52,7 +63,17 @@ export const PromptRowActionsCell: React.FunctionComponent<
<DropdownMenuContent align="end" className="w-52">
<DropdownMenuItem
onClick={() => {
setOpen(true);
setOpen(EDIT_KEY);
resetKeyRef.current = resetKeyRef.current + 1;
}}
>
<Pencil className="mr-2 size-4" />
Edit
</DropdownMenuItem>

<DropdownMenuItem
onClick={() => {
setOpen(DELETE_KEY);
resetKeyRef.current = resetKeyRef.current + 1;
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import ColumnsButton from "@/components/shared/ColumnsButton/ColumnsButton";
import usePromptsList from "@/api/prompts/usePromptsList";
import { Prompt } from "@/types/prompts";
import { PromptRowActionsCell } from "@/components/pages/PromptsPage/PromptRowActionsCell";
import AddPromptDialog from "@/components/pages/PromptsPage/AddPromptDialog";
import AddEditPromptDialog from "@/components/pages/PromptsPage/AddEditPromptDialog";
import TagNameCell from "@/components/pages/PromptsPage/TagNameCell";
import { useNavigate } from "@tanstack/react-router";

Expand Down Expand Up @@ -207,7 +207,7 @@ const PromptsPage: React.FunctionComponent = () => {
total={total}
></DataTablePagination>
</div>
<AddPromptDialog
<AddEditPromptDialog
key={resetDialogKeyRef.current}
open={openDialog}
setOpen={setOpenDialog}
Expand Down

0 comments on commit 513161e

Please sign in to comment.