diff --git a/apps/evalite-ui/app/components/display-input.tsx b/apps/evalite-ui/app/components/display-input.tsx index 5570073..a583a6e 100644 --- a/apps/evalite-ui/app/components/display-input.tsx +++ b/apps/evalite-ui/app/components/display-input.tsx @@ -1,4 +1,4 @@ -import { useState, useRef, useLayoutEffect } from "react"; +import React, { useState, useRef, useLayoutEffect, Fragment } from "react"; import ReactMarkdown from "react-markdown"; import { Button } from "./ui/button"; import { ChevronDown } from "lucide-react"; @@ -11,34 +11,49 @@ type DisplayStatus = | "showing-show-more-button" | "showing-more"; -const DisplayText = ({ input }: { input: string }) => { +const DisplayText = ({ + input, + shouldTruncateText, + Wrapper, +}: { + input: string; + Wrapper: React.ElementType<{ children: React.ReactNode }>; + shouldTruncateText: boolean; +}) => { const [status, setStatus] = useState( "no-show-more-button-required" ); const contentRef = useRef(null); useLayoutEffect(() => { - if (contentRef.current) { + if (contentRef.current && shouldTruncateText) { if (contentRef.current.scrollHeight > MAX_HEIGHT) { setStatus("showing-show-more-button"); } } - }, [input]); + }, [input, shouldTruncateText]); return (
-
- {input} -
- {status === "showing-show-more-button" && ( + +
+ {input} +
+
+ {status === "showing-show-more-button" && shouldTruncateText && ( ); diff --git a/apps/evalite-ui/app/routes/eval.$name.trace.$index.tsx b/apps/evalite-ui/app/routes/eval.$name.trace.$index.tsx index 1406ad4..f0dbd2d 100644 --- a/apps/evalite-ui/app/routes/eval.$name.trace.$index.tsx +++ b/apps/evalite-ui/app/routes/eval.$name.trace.$index.tsx @@ -1,25 +1,37 @@ import { getEvalResult } from "@evalite/core/sdk"; -import { useLoaderData, type ClientLoaderFunctionArgs } from "@remix-run/react"; -import { PlusIcon } from "lucide-react"; -import { SidebarRight } from "~/components/sidebar-right"; +import { + Link, + useLoaderData, + type ClientLoaderFunctionArgs, +} from "@remix-run/react"; +import { SidebarCloseIcon } from "lucide-react"; +import { DisplayInput } from "~/components/display-input"; import { Breadcrumb, BreadcrumbItem, - BreadcrumbLink, BreadcrumbList, - BreadcrumbPage, } from "~/components/ui/breadcrumb"; +import { Button } from "~/components/ui/button"; import { Separator } from "~/components/ui/separator"; import { Sidebar, SidebarContent, - SidebarFooter, SidebarHeader, - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, } from "~/components/ui/sidebar"; +const SidebarSection = ({ + title, + input, +}: { + title: string; + input: unknown; +}) => ( +
+

{title}

+ +
+); + export const clientLoader = async (args: ClientLoaderFunctionArgs) => { const result = await getEvalResult({ name: args.params.name!, @@ -40,31 +52,37 @@ export default function Page() { side="right" className="sticky hidden top-0 h-svh w-[400px] border-l" > - -
- - Trace - - - - Hello - - Hello - - + +
+ +
+ Trace + + + {result.duration}ms + {/* + Hello */} + + +
+
- - - - - - - New Calendar - - - - + + + + {result.expected ? ( + <> + + + + ) : null} + + ); } diff --git a/apps/evalite-ui/app/routes/eval.$name.tsx b/apps/evalite-ui/app/routes/eval.$name.tsx index ea385bb..7776e4a 100644 --- a/apps/evalite-ui/app/routes/eval.$name.tsx +++ b/apps/evalite-ui/app/routes/eval.$name.tsx @@ -1,11 +1,12 @@ import { getEvalRunsByName } from "@evalite/core/sdk"; import type { MetaFunction } from "@remix-run/node"; import { + Link, Outlet, useLoaderData, type ClientLoaderFunctionArgs, } from "@remix-run/react"; -import { useContext } from "react"; +import React, { useContext } from "react"; import { DisplayInput } from "~/components/display-input"; import { InnerPageLayout } from "~/components/page-layout"; import { getScoreState, Score } from "~/components/score"; @@ -83,18 +84,35 @@ export default function Page() { - {evaluation.results.map((result) => { + {evaluation.results.map((result, index) => { + const Wrapper = (props: { children: React.ReactNode }) => ( + + {props.children} + + ); return ( - + - + {showExpectedColumn && ( - + )} {result.scores.map((scorer, index) => { @@ -106,17 +124,21 @@ export default function Page() { key={scorer.name} className={cn(index === 0 && "border-l")} > - + + + ); })} diff --git a/apps/evalite-ui/app/utils.test.ts b/apps/evalite-ui/app/utils.test.ts new file mode 100644 index 0000000..3fe336d --- /dev/null +++ b/apps/evalite-ui/app/utils.test.ts @@ -0,0 +1,18 @@ +import { describe, it, expect } from "vitest"; +import { scoreToPercent, formatTime } from "./utils"; + +describe("scoreToPercent", () => { + it("should convert score to percent", () => { + expect(scoreToPercent(0.123)).toBe("12.3%"); + expect(scoreToPercent(0.456)).toBe("45.6%"); + expect(scoreToPercent(1)).toBe("100%"); + }); +}); + +describe("formatTime", () => { + it("should format time correctly", () => { + expect(formatTime(200)).toBe("200ms"); + expect(formatTime(1243)).toBe("1.2s"); + expect(formatTime(4302)).toBe("4.3s"); + }); +}); diff --git a/apps/evalite-ui/app/utils.ts b/apps/evalite-ui/app/utils.ts index 6026347..d209812 100644 --- a/apps/evalite-ui/app/utils.ts +++ b/apps/evalite-ui/app/utils.ts @@ -1,3 +1,10 @@ export const scoreToPercent = (score: number) => { return `${Math.round(score * 1000) / 10}%`; }; + +export const formatTime = (time: number) => { + if (time < 1000) { + return `${time}ms`; + } + return `${(time / 1000).toFixed(1)}s`; +}; diff --git a/apps/evalite-ui/package.json b/apps/evalite-ui/package.json index 8a36ab4..4d38655 100644 --- a/apps/evalite-ui/package.json +++ b/apps/evalite-ui/package.json @@ -8,7 +8,8 @@ "after-build": "rm -rf ../../packages/evalite-core/dist/ui && cp -r build/client ../../packages/evalite-core/dist/ui", "dev": "remix vite:dev", "start": "remix-serve ./build/server/index.js", - "lint": "tsc" + "lint": "tsc", + "test": "vitest run" }, "dependencies": { "react-json-tree": "^0.19.0",