From e4c101a843c52d8717852f83fc56b30fa2dae083 Mon Sep 17 00:00:00 2001 From: Kyle Corbitt Date: Wed, 5 Jul 2023 17:28:46 -0700 Subject: [PATCH] change outputs table to make room for evals --- .../OutputsTable/NewEvaluationButton.tsx | 40 ++++++++++ src/components/OutputsTable/ScenarioRow.tsx | 39 ++++++++++ src/components/OutputsTable/index.tsx | 75 +++++++------------ 3 files changed, 108 insertions(+), 46 deletions(-) create mode 100644 src/components/OutputsTable/NewEvaluationButton.tsx create mode 100644 src/components/OutputsTable/ScenarioRow.tsx diff --git a/src/components/OutputsTable/NewEvaluationButton.tsx b/src/components/OutputsTable/NewEvaluationButton.tsx new file mode 100644 index 0000000..58e93fe --- /dev/null +++ b/src/components/OutputsTable/NewEvaluationButton.tsx @@ -0,0 +1,40 @@ +import { Button, type ButtonProps, HStack, Spinner, Icon } from "@chakra-ui/react"; +import { BsPlus } from "react-icons/bs"; +import { api } from "~/utils/api"; +import { useExperiment, useHandledAsyncCallback } from "~/utils/hooks"; + +// Extracted Button styling into reusable component +const StyledButton = ({ children, onClick }: ButtonProps) => ( + +); + +export default function NewEvaluationButton() { + const experiment = useExperiment(); + const mutation = api.scenarios.create.useMutation(); + const utils = api.useContext(); + + const [onClick] = useHandledAsyncCallback(async () => { + if (!experiment.data) return; + await mutation.mutateAsync({ + experimentId: experiment.data.id, + }); + await utils.scenarios.list.invalidate(); + }, [mutation]); + + return ( + + + + Add Evaluation + + + ); +} diff --git a/src/components/OutputsTable/ScenarioRow.tsx b/src/components/OutputsTable/ScenarioRow.tsx new file mode 100644 index 0000000..d12e1dc --- /dev/null +++ b/src/components/OutputsTable/ScenarioRow.tsx @@ -0,0 +1,39 @@ +import { Box, GridItem } from "@chakra-ui/react"; +import React, { useState } from "react"; +import { cellPadding } from "../constants"; +import OutputCell from "./OutputCell"; +import ScenarioEditor from "./ScenarioEditor"; +import type { PromptVariant, Scenario } from "./types"; + +const ScenarioRow = (props: { scenario: Scenario; variants: PromptVariant[] }) => { + const [isHovered, setIsHovered] = useState(false); + + const highlightStyle = { backgroundColor: "gray.50" }; + + return ( + <> + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + sx={isHovered ? highlightStyle : undefined} + borderLeftWidth={1} + > + + + {props.variants.map((variant) => ( + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + sx={isHovered ? highlightStyle : undefined} + > + + + + + ))} + + ); +}; + +export default ScenarioRow; diff --git a/src/components/OutputsTable/index.tsx b/src/components/OutputsTable/index.tsx index e5bc185..e669471 100644 --- a/src/components/OutputsTable/index.tsx +++ b/src/components/OutputsTable/index.tsx @@ -1,56 +1,20 @@ -import { Box, Grid, GridItem, type SystemStyleObject } from "@chakra-ui/react"; -import React, { useState } from "react"; +import { Grid, GridItem, Heading, type SystemStyleObject } from "@chakra-ui/react"; +import ScenarioHeader from "~/server/ScenarioHeader"; import { api } from "~/utils/api"; +import NewEvaluationButton from "./NewEvaluationButton"; import NewScenarioButton from "./NewScenarioButton"; import NewVariantButton from "./NewVariantButton"; -import OutputCell from "./OutputCell"; -import ScenarioEditor from "./ScenarioEditor"; +import ScenarioRow from "./ScenarioRow"; import VariantConfigEditor from "./VariantConfigEditor"; import VariantHeader from "./VariantHeader"; -import type { Scenario, PromptVariant } from "./types"; -import ScenarioHeader from "~/server/ScenarioHeader"; -import { cellPadding } from "../constants"; const stickyHeaderStyle: SystemStyleObject = { position: "sticky", - top: 0, + top: "-1px", backgroundColor: "#fff", zIndex: 1, }; -const ScenarioRow = (props: { scenario: Scenario; variants: PromptVariant[] }) => { - const [isHovered, setIsHovered] = useState(false); - - const highlightStyle = { - backgroundColor: "gray.50", // or any color you prefer - }; - - return ( - - setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} - sx={isHovered ? highlightStyle : undefined} - borderLeftWidth={1} - > - - - {props.variants.map((variant) => ( - setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} - sx={isHovered ? highlightStyle : undefined} - > - - - - - ))} - - ); -}; - export default function OutputsTable({ experimentId }: { experimentId: string | undefined }) { const variants = api.promptVariants.list.useQuery( { experimentId: experimentId as string }, @@ -64,6 +28,8 @@ export default function OutputsTable({ experimentId }: { experimentId: string | if (!variants.data || !scenarios.data) return null; + const allCols = variants.data.length + 1; + return ( - - - + {variants.data.map((variant) => ( ))} *" selector on Grid style={{ borderRightWidth: 0, borderBottomWidth: 0 }} @@ -103,12 +67,31 @@ export default function OutputsTable({ experimentId }: { experimentId: string | ))} + + + + + {scenarios.data.map((scenario) => ( ))} - + + {/* + + Evaluations + + + + + */} ); }