->(({ className, ...props }, ref) => (
- [role=checkbox]]:translate-y-[2px]',
- className
- )}
- {...props}
- />
-));
-TableCell.displayName = 'TableCell';
-
-const TableCaption = React.forwardRef<
- HTMLTableCaptionElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-));
-TableCaption.displayName = 'TableCaption';
-
-export {
- Table,
- TableHeader,
- TableBody,
- TableFooter,
- TableHead,
- TableRow,
- TableCell,
- TableCaption,
-};
diff --git a/ui-pages-router/src/components/ui/tabs.tsx b/ui-pages-router/src/components/ui/tabs.tsx
deleted file mode 100644
index 7646fcd..0000000
--- a/ui-pages-router/src/components/ui/tabs.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-'use client';
-
-import * as React from 'react';
-import * as TabsPrimitive from '@radix-ui/react-tabs';
-
-import { cn } from '@/lib/utils';
-
-const Tabs = TabsPrimitive.Root;
-
-const TabsList = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-TabsList.displayName = TabsPrimitive.List.displayName;
-
-const TabsTrigger = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
-
-const TabsContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-TabsContent.displayName = TabsPrimitive.Content.displayName;
-
-export { Tabs, TabsList, TabsTrigger, TabsContent };
diff --git a/ui-pages-router/src/components/ui/toggle-group.tsx b/ui-pages-router/src/components/ui/toggle-group.tsx
deleted file mode 100644
index f104e83..0000000
--- a/ui-pages-router/src/components/ui/toggle-group.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-'use client';
-
-import * as React from 'react';
-import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
-import { VariantProps } from 'class-variance-authority';
-
-import { cn } from '@/lib/utils';
-import { toggleVariants } from '@/components/ui/toggle';
-
-const ToggleGroupContext = React.createContext<
- VariantProps
->({
- size: 'default',
- variant: 'default',
-});
-
-const ToggleGroup = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef &
- VariantProps
->(({ className, variant, size, children, ...props }, ref) => (
-
-
- {children}
-
-
-));
-
-ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
-
-const ToggleGroupItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef &
- VariantProps
->(({ className, children, variant, size, ...props }, ref) => {
- const context = React.useContext(ToggleGroupContext);
-
- return (
-
- {children}
-
- );
-});
-
-ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
-
-export { ToggleGroup, ToggleGroupItem };
diff --git a/ui-pages-router/src/components/ui/toggle.tsx b/ui-pages-router/src/components/ui/toggle.tsx
deleted file mode 100644
index dcf1b73..0000000
--- a/ui-pages-router/src/components/ui/toggle.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-'use client';
-
-import * as React from 'react';
-import * as TogglePrimitive from '@radix-ui/react-toggle';
-import { cva, type VariantProps } from 'class-variance-authority';
-
-import { cn } from '@/lib/utils';
-
-const toggleVariants = cva(
- // eslint-disable-next-line max-len
- 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground',
- {
- variants: {
- variant: {
- default: 'bg-transparent',
- outline:
- // eslint-disable-next-line max-len
- 'border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground',
- },
- size: {
- default: 'h-9 px-3',
- sm: 'h-8 px-2',
- lg: 'h-10 px-3',
- },
- },
- defaultVariants: {
- variant: 'default',
- size: 'default',
- },
- }
-);
-
-const Toggle = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef &
- VariantProps
->(({ className, variant, size, ...props }, ref) => (
-
-));
-
-Toggle.displayName = TogglePrimitive.Root.displayName;
-
-export { Toggle, toggleVariants };
diff --git a/ui-pages-router/src/lib/utils.ts b/ui-pages-router/src/lib/utils.ts
deleted file mode 100644
index 9ad0df4..0000000
--- a/ui-pages-router/src/lib/utils.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { type ClassValue, clsx } from 'clsx';
-import { twMerge } from 'tailwind-merge';
-
-export function cn(...inputs: ClassValue[]) {
- return twMerge(clsx(inputs));
-}
diff --git a/ui-pages-router/src/lib/utils/build-tree-from-object.ts b/ui-pages-router/src/lib/utils/build-tree-from-object.ts
deleted file mode 100644
index 98e8fcd..0000000
--- a/ui-pages-router/src/lib/utils/build-tree-from-object.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { TraceTreeNode } from '@/models/trace-detail-response';
-import { compareTimestamps } from '@/lib/utils/compare-timestamps-to-nano';
-
-export function buildTreeFromObject(aggregatedObject: TraceTreeNode): TraceTreeNode {
- const rootNode = { ...aggregatedObject, children: [] };
- const flatChildren = aggregatedObject.children;
- flatChildren.sort((a, b) => {
- if (a.depth !== undefined && b.depth !== undefined) {
- // Handle Records that were for when we had execution_order (old format)
- if (a.depth === b.depth) {
- if (a.dotted_order !== undefined && b.dotted_order !== undefined) {
- console.debug('Using Dotted Order to sort');
-
- const aDottedOrder = a.dotted_order.split('.');
- const bDottedOrder = b.dotted_order.split('.');
-
- const aLastElement = aDottedOrder.pop();
- const bLastElement = bDottedOrder.pop();
-
- const aDate = aLastElement!.substring(0, 22)
- .replace(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\d{3})(\d{3})Z$/,
- '$1-$2-$3T$4:$5:$6.$7$8Z');
- const bDate = bLastElement!.substring(0, 22)
- .replace(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\d{3})(\d{3})Z$/,
- '$1-$2-$3T$4:$5:$6.$7$8Z');
-
- return compareTimestamps(aDate, bDate);
- } else if (a.execution_order !== undefined && b.execution_order !== undefined) {
- console.debug('Using Execution Order to sort');
- return a.execution_order - b.execution_order;
- }
- }
- return a.depth - b.depth;
- }
- return 0;
- });
-
- const nodesMap = new Map();
- nodesMap.set(aggregatedObject.run_id, rootNode);
- flatChildren.forEach(child => {
- const node = { ...child, children: [] };
- nodesMap.set(child.run_id, node);
- });
-
- flatChildren.forEach(child => {
- const parentNode = nodesMap.get(child.parent_run_id)!;
- if (parentNode) {
- parentNode.children.push(nodesMap.get(child.run_id)!);
- }
- });
- return rootNode;
-}
diff --git a/ui-pages-router/src/lib/utils/compare-timestamps-to-nano.ts b/ui-pages-router/src/lib/utils/compare-timestamps-to-nano.ts
deleted file mode 100644
index 413e692..0000000
--- a/ui-pages-router/src/lib/utils/compare-timestamps-to-nano.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-export function compareTimestamps(ts1: string, ts2: string): number {
- // Extract the millisecond part and the nanosecond part
- const regex = /(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3})(\d*)Z/;
- const match1 = ts1.match(regex);
- const match2 = ts2.match(regex);
-
- if (!match1 || !match2) throw new Error('Invalid timestamp format');
-
- const date1 = new Date(match1[1] + 'Z');
- const date2 = new Date(match2[1] + 'Z');
- const nano1 = parseInt(match1[2].padEnd(6, '0'), 10); // Pad to ensure microseconds
- const nano2 = parseInt(match2[2].padEnd(6, '0'), 10);
-
- // First compare the millisecond part
- if (date1 > date2) return 1;
- if (date1 < date2) return -1;
-
- // Then compare the nanosecond part, if milliseconds are equal
- if (nano1 > nano2) return 1;
- if (nano1 < nano2) return -1;
-
- // Dates are exactly equal
- return 0;
-}
diff --git a/ui-pages-router/src/lib/utils/config.ts b/ui-pages-router/src/lib/utils/config.ts
deleted file mode 100644
index 02d320b..0000000
--- a/ui-pages-router/src/lib/utils/config.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { z } from 'zod';
-
-//TODO Add in missing environment variables for Auth
-const configSchema = z.object({
- langtraceApiUrl: z.string().url(),
-});
-
-type Config = z.infer;
-
-const config: Config = configSchema.parse({
- langtraceApiUrl: process.env.LANGTRACE_API_URL,
-});
-
-export default config;
diff --git a/ui-pages-router/src/lib/utils/convert-timestamp-to-datetime.ts b/ui-pages-router/src/lib/utils/convert-timestamp-to-datetime.ts
deleted file mode 100644
index 4cffd85..0000000
--- a/ui-pages-router/src/lib/utils/convert-timestamp-to-datetime.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-
-interface DateTime {
- date: string;
- time: string;
-}
-
-export function convertTimestampToDatetime(timestamp: string): DateTime {
- const dateObj = new Date(timestamp);
-
- const date = dateObj.toLocaleDateString('en-GB', {
- day: '2-digit',
- month: '2-digit',
- year: 'numeric'
- });
- const time = dateObj.toLocaleTimeString('en-GB', {
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit',
- hour12: false
- });
-
- return { date, time };
-}
diff --git a/ui-pages-router/src/lib/utils/get-parent-page-from-url-path.ts b/ui-pages-router/src/lib/utils/get-parent-page-from-url-path.ts
deleted file mode 100644
index d3f8893..0000000
--- a/ui-pages-router/src/lib/utils/get-parent-page-from-url-path.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export function getParentPageFromUrlPath(path: string): string {
- const lastSlashIndex = path.lastIndexOf('/');
- return path.substring(0, lastSlashIndex);
-}
diff --git a/ui-pages-router/src/middleware.ts b/ui-pages-router/src/middleware.ts
deleted file mode 100644
index a965821..0000000
--- a/ui-pages-router/src/middleware.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { NextResponse } from 'next/server';
-import type { NextRequest } from 'next/server';
-import { getToken } from 'next-auth/jwt';
-
-export async function middleware(req: NextRequest) {
- const enableAuth = process.env.NEXTAUTH_ENABLE === 'true';
-
- if (!enableAuth) {
- return NextResponse.next();
- }
-
-
- const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
-
- const { pathname } = req.nextUrl;
-
- if (pathname.includes('/api/auth') || token) {
- return NextResponse.next();
- }
-
- if (!token && pathname !== '/api/auth/signin') {
- const url = req.nextUrl.clone();
- url.pathname = '/api/auth/signin';
- return NextResponse.redirect(url);
- }
-}
diff --git a/ui-pages-router/src/models/projects-response.ts b/ui-pages-router/src/models/projects-response.ts
deleted file mode 100644
index 1d7fc9c..0000000
--- a/ui-pages-router/src/models/projects-response.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export interface ProjectResponse {
- project_name: string;
- tracesLast24Hours: number;
- tracesLast7Days: number;
- tracesLast30Days: number;
-}
diff --git a/ui-pages-router/src/models/trace-detail-response.ts b/ui-pages-router/src/models/trace-detail-response.ts
deleted file mode 100644
index bbf4c66..0000000
--- a/ui-pages-router/src/models/trace-detail-response.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-export interface TraceTreeNode {
- run_id: string;
- name: string;
- start_time: string;
- end_time: string | null;
- metadata: { [key: string]: any };
- outputs: { [key: string]: any };
- inputs: { [key: string]: any };
- error: string | null;
- session_name: string;
- run_type: string;
- latency: number;
- parent_run_id: string;
- children: TraceTreeNode[];
- totalInputTokenCount?: number;
- totalInputCost?: number;
- totalOutputCost?: number;
- totalOutputTokenCount?: number;
- totalCost?: number;
- totalTokens?: number;
- depth?: number;
- feedback?: { [key: string]: any }; //TODO Make this a proper type
-
- execution_order?: number; //TODO This is only used for old format (pre version....)
-
- trace_id?: string; //TODO This is only used for new format (post version....)
- dotted_order?: string; //TODO This is only used for new format (post version....)
-
-}
diff --git a/ui-pages-router/src/models/traces-response.ts b/ui-pages-router/src/models/traces-response.ts
deleted file mode 100644
index 06541f9..0000000
--- a/ui-pages-router/src/models/traces-response.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { TraceTreeNode } from '@/models/trace-detail-response';
-
-export interface TracePercentile {
- percentile: number;
- latency: number;
-}
-
-export interface FeedbackCount {
- key: string;
- counts: { [key: string]: number };
-}
-
-
-export interface TracesResponse {
- traces: TraceTreeNode[];
- latency_percentiles: TracePercentile[];
- feedback_counts: FeedbackCount[];
-}
diff --git a/ui-pages-router/src/pages/_app.tsx b/ui-pages-router/src/pages/_app.tsx
deleted file mode 100644
index 384ded6..0000000
--- a/ui-pages-router/src/pages/_app.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import '../styles/globals.scss';
-import '../styles/globals.css';
-import type { AppProps } from 'next/app';
-import Head from 'next/head';
-import { SessionProvider } from 'next-auth/react';
-
-function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
-
- return (
- <>
-
- Langtrace
-
-
-
-
- >
- );
-}
-
-export default MyApp;
diff --git a/ui-pages-router/src/pages/_document.tsx b/ui-pages-router/src/pages/_document.tsx
deleted file mode 100644
index 40a887e..0000000
--- a/ui-pages-router/src/pages/_document.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import Document, { Html, Head, Main, NextScript } from 'next/document';
-import { ThemeProvider } from '@/components/theme-provider';
-
-class MyDocument extends Document {
- render() {
- return (
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-export default MyDocument;
diff --git a/ui-pages-router/src/pages/api/auth/[...nextauth].ts b/ui-pages-router/src/pages/api/auth/[...nextauth].ts
deleted file mode 100644
index 658fd40..0000000
--- a/ui-pages-router/src/pages/api/auth/[...nextauth].ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import NextAuth, { NextAuthOptions, Profile } from 'next-auth';
-import GithubProvider from 'next-auth/providers/github';
-import { NextApiRequest, NextApiResponse } from 'next';
-
-const enableAuth = process.env.NEXTAUTH_ENABLE === 'true';
-
-interface GitHubProfile extends Profile {
- login: string;
-
-}
-
-const options = {
- providers: [
- GithubProvider({
- clientId: process.env.NEXTAUTH_GITHUB_ID!,
- clientSecret: process.env.NEXTAUTH_GITHUB_SECRET!,
- authorization: {
- params: {
- scope: 'read:user,user:email,read:org',
- },
- },
- }),
- ],
- callbacks: {
- async signIn({ account, profile }) {
- if (account?.provider === 'github' &&
- (process.env.NEXTAUTH_GITHUB_ORGANISATION ?? '').trim() !== '') {
- const orgName = process.env.NEXTAUTH_GITHUB_ORGANISATION;
- const token = account.access_token;
- const url =
- `https://api.github.com/orgs/${orgName}/members/${(profile as GitHubProfile).login}`;
- const response = await fetch(url, {
- headers: {
- Authorization: `token ${token}`,
- },
- });
- return response.ok;
- }
- // If not GitHub, continue the sign-in process
- return true;
- },
- },
-} satisfies NextAuthOptions;
-
-// eslint-disable-next-line import/no-anonymous-default-export
-export default (req: NextApiRequest, res: NextApiResponse) => {
- if (enableAuth) {
- return NextAuth(req, res, options);
- } else {
- res.status(200).json({ message: 'Authentication bypassed' });
- }
-};
diff --git a/ui-pages-router/src/pages/index.tsx b/ui-pages-router/src/pages/index.tsx
deleted file mode 100644
index c68fa8c..0000000
--- a/ui-pages-router/src/pages/index.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-import { RiLoginBoxLine } from 'react-icons/ri';
-import { signIn, useSession } from 'next-auth/react';
-import AppBar from '@/components/AppBar';
-import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
-import { Button, buttonVariants } from '@/components/ui/button';
-import React from 'react';
-import Link from 'next/link';
-import { BarChartIcon, GearIcon, StackIcon } from '@radix-ui/react-icons';
-
-const Home = () => {
- const { status } = useSession();
-
- const quickLinks = [
- {
- name: 'CapGPT Production',
- url: '/projects/capgpt-production/traces'
- },
- {
- name: 'CapGPT Dev',
- url: '/projects/capgpt-dev/traces'
- },
- {
- name: 'CapGPT Local',
- url: '/projects/capgpt-local/traces'
- },
- ];
-
-
- if (status === 'loading') {
- return Hang on there... ;
- }
- if (status === 'authenticated') {
- return (
-
-
-
-
-
-
-
- Actions
-
-
-
-
-
- Projects
-
-
- Settings
-
-
-
-
-
-
-
-
-
-
- Quick Launch
-
-
-
-
- {quickLinks.map((link, index) => (
-
- {link.name}
-
- ))}
-
-
-
-
-
-
-
-
- );
- }
-
- return (
- <>
-
-
-
- Langtrace
-
-
-
- View your Langchain data
-
-
-
-
- >
- );
-};
-
-export default Home;
diff --git a/ui-pages-router/src/pages/projects/[projectId].tsx b/ui-pages-router/src/pages/projects/[projectId].tsx
deleted file mode 100644
index 9fc4cb1..0000000
--- a/ui-pages-router/src/pages/projects/[projectId].tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { GetServerSidePropsContext } from 'next';
-import React from 'react';
-import { getParentPageFromUrlPath } from '@/lib/utils/get-parent-page-from-url-path';
-import { usePathname } from 'next/navigation';
-import AppBar from '@/components/AppBar';
-import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
-import Link from 'next/link';
-import { buttonVariants } from '@/components/ui/button';
-
-interface ProjectDetailsPageProps {
- projectId: string;
-}
-
-const ProjectDetailsPage: React.FC = ({ projectId }) => {
- const breadcrumbItems = [
- { name: 'Home', path: '/' },
- { name: 'Projects', path: getParentPageFromUrlPath(usePathname()) },
- { name: `${projectId}`, path: undefined }
- ];
-
- return <>
-
-
-
-
- {projectId}
-
-
-
-
-
-
- >
- ;
-};
-
-
-export async function getServerSideProps(context: GetServerSidePropsContext) {
- try {
- const projectId = context.params?.projectId as string;
-
- return { props: { projectId } };
- } catch (error) {
- return { props: { error: 'Failed to fetch trace data' } };
- }
-}
-
-export default ProjectDetailsPage;
diff --git a/ui-pages-router/src/pages/projects/[projectId]/traces/[traceId].tsx b/ui-pages-router/src/pages/projects/[projectId]/traces/[traceId].tsx
deleted file mode 100644
index 0807915..0000000
--- a/ui-pages-router/src/pages/projects/[projectId]/traces/[traceId].tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import TraceTree from '../../../../components/TraceTree';
-import TraceDetailsPanel from '../../../../components/TraceDetailsPanel';
-import { getTraceTree } from '@/services/trace-service';
-import { TraceTreeNode } from '@/models/trace-detail-response';
-import { GetServerSidePropsContext } from 'next';
-import { usePathname } from 'next/navigation';
-import { getParentPageFromUrlPath } from '@/lib/utils/get-parent-page-from-url-path';
-import AppBar from '@/components/AppBar';
-import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/ui/resizable';
-
-interface TraceDetailsPageProps {
- projectId: string;
- traceData: TraceTreeNode;
-}
-
-const TraceDetailsPage: React.FC = ({ projectId, traceData }) => {
- const [expandedNodes, setExpandedNodes] = useState(new Set());
- const [selectedTrace, setSelectedTrace] = useState(null);
-
- useEffect(() => {
- const runIdToExpand = traceData
- .children.filter((child) => {
- return child.depth === 0;
- })
- .map((child) => child.run_id);
- setExpandedNodes(new Set([traceData.run_id, ...runIdToExpand]));
- setSelectedTrace(traceData);
- }, [traceData]);
-
- const breadcrumbItems = [
- { name: 'Home', path: '/' },
- { name: 'Projects', path: '/projects' },
- { name: `${projectId}`, path: `/projects/${projectId}` },
- { name: 'Traces', path: getParentPageFromUrlPath(usePathname()) },
- { name: `${traceData.name} @ ${traceData.start_time}`, path: undefined }
- ];
-
- return (
-
- );
-};
-
-export async function getServerSideProps(context: GetServerSidePropsContext) {
- try {
- const traceId = context.params?.traceId as string;
- const projectId = context.params?.projectId as string;
- const traceData = await getTraceTree(projectId, traceId);
- return { props: { projectId, traceData } };
- } catch (error) {
- return { props: { error: 'Failed to fetch trace data' } };
- }
-}
-
-export default TraceDetailsPage;
diff --git a/ui-pages-router/src/pages/projects/[projectId]/traces/index.tsx b/ui-pages-router/src/pages/projects/[projectId]/traces/index.tsx
deleted file mode 100644
index 4fba115..0000000
--- a/ui-pages-router/src/pages/projects/[projectId]/traces/index.tsx
+++ /dev/null
@@ -1,246 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import { getTraces } from '@/services/trace-service';
-import { useRouter } from 'next/router';
-import { GetServerSidePropsContext } from 'next';
-import StatsPanel from '@/components/FilterPanel';
-import TraceTable from '../../../../components/TraceTable';
-import { FeedbackCount, TracePercentile } from '@/models/traces-response';
-import { TraceTreeNode } from '@/models/trace-detail-response';
-import AppBar from '@/components/AppBar';
-import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/ui/resizable';
-
-interface DateRangeInt {
- startDate: Date;
- endDate: Date | null;
-
-}
-
-const handlePredefinedRange = (range: string): DateRangeInt => {
- const now = new Date();
- if (range === '1h') {
- return {
- startDate: new Date(now.getTime() - 60 * 60 * 1000),
- endDate: null,
- };
-
- } else if (range === '3h') {
- return {
- startDate: new Date(now.getTime() - 3 * 60 * 60 * 1000),
- endDate: null,
- };
- } else if (range === '12h') {
- return {
- startDate: new Date(now.getTime() - 12 * 60 * 60 * 1000),
- endDate: null,
- };
- } else if (range === '24h') {
- return {
- startDate: new Date(now.getTime() - 24 * 60 * 60 * 1000),
- endDate: null,
- };
- } else if (range === '7d') {
- return {
- startDate: new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000),
- endDate: null,
- };
- } else if (range === '30d') {
- return {
- startDate: new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000),
- endDate: null,
- };
- }
- throw new Error('Invalid range');
-};
-
-
-interface TracesProps {
- projectId: string;
- traces: TraceTreeNode[];
- latencyPercentiles: TracePercentile[];
- feedbackCounts: FeedbackCount[];
-}
-
-export interface FeedbackFilters {
- [key: string]: string[];
-}
-
-
-const Traces: React.FC = ({
- projectId,
- traces,
- latencyPercentiles,
- feedbackCounts
-}) => {
- const router = useRouter();
-
- const breadcrumbItems = [
- { name: 'Home', path: '/' },
- { name: 'Projects', path: '/projects' },
- { name: `${projectId}`, path: `/projects/${projectId}` },
- { name: 'Traces', path: undefined },
- ];
-
- const parseFeedbackFilters = (filters: string | string[] | undefined): FeedbackFilters => {
- if (typeof filters === 'string') {
- try {
- const feedbackFilters: FeedbackFilters = JSON.parse(filters);
- Object.keys(feedbackFilters).forEach(key => {
- feedbackFilters[key].sort();
- });
- return feedbackFilters;
- } catch {
- return {};
- }
- }
- return {};
- };
-
-
- const initialStartDate = router.query.startDate
- ? new Date(router.query.startDate as string)
- : null;
- const initialEndDate = router.query.endDate
- ? new Date(router.query.endDate as string)
- : null;
- const initialFeedbackFilters = parseFeedbackFilters(router.query.feedbackFilters);
- const initialInLast = router.query.inLast as string | null;
-
- const [startDate, setStartDate] =
- useState(initialStartDate);
- const [endDate, setEndDate] =
- useState(initialEndDate);
- const [feedbackFilters, setFeedbackFilters] =
- useState(initialFeedbackFilters);
- const [inLast, setInLast] =
- useState(initialInLast);
-
- useEffect(() => {
- if (
- startDate !== initialStartDate ||
- endDate !== initialEndDate ||
- JSON.stringify(feedbackFilters) !== JSON.stringify(initialFeedbackFilters) ||
- initialInLast !== inLast
- ) {
- const formattedStart = startDate?.toISOString();
- const formattedEnd = endDate?.toISOString();
- const newQuery = { ...router.query };
-
- if (formattedStart) {
- newQuery.startDate = formattedStart;
- } else {
- delete newQuery.startDate;
- }
-
- if (formattedEnd) {
- newQuery.endDate = formattedEnd;
- } else {
- delete newQuery.endDate;
- }
-
- if (inLast) {
- newQuery.inLast = inLast;
- const dates = handlePredefinedRange(inLast as string);
- newQuery.startDate = dates.startDate.toISOString();
- newQuery.endDate = dates?.endDate?.toISOString();
- } else {
- delete newQuery.inLast;
- }
-
- if (Object.keys(feedbackFilters).length > 0) {
- newQuery.feedbackFilters = JSON.stringify(feedbackFilters);
- } else {
- delete newQuery.feedbackFilters;
- }
-
- router.push({
- pathname: router.pathname,
- query: newQuery,
- }).then(() => undefined);
- }
- }, [startDate, endDate, feedbackFilters, inLast]);
-
-
- const handleDropdownChange = (value: string) => {
- // handlePredefinedRange(event.target.value);
- setInLast(value);
- };
-
- const handleFeedbackSelect = (key: string, value: string, isSelected: boolean) => {
- setFeedbackFilters(prevFilters => {
- const newFilters = { ...prevFilters };
-
- if (isSelected) {
- if (!newFilters[key]) {
- newFilters[key] = [];
- }
- if (!newFilters[key].includes(value)) {
- newFilters[key].push(value);
- }
- } else {
- newFilters[key] = (newFilters[key] ?? []).filter(v => v !== value);
- if (newFilters[key].length === 0) {
- delete newFilters[key];
- }
- }
-
- return newFilters;
- });
- };
-
- return (
-
- );
-};
-
-
-export async function getServerSideProps(context: GetServerSidePropsContext) {
- const projectId = context.params?.projectId as string;
-
- const { query } = context;
- let { startDate, endDate } = query;
- const { feedbackFilters, inLast } = query;
-
- if (inLast) {
- const dates = handlePredefinedRange(inLast as string);
- startDate = dates.startDate.toISOString();
- endDate = dates?.endDate?.toISOString();
- }
-
- const data = await getTraces(
- projectId,
- startDate as string,
- endDate as string,
- feedbackFilters as string
- );
-
- return {
- props: {
- projectId: projectId,
- traces: data.traces,
- latencyPercentiles: data.latency_percentiles,
- feedbackCounts: data.feedback_counts
- }
- };
-}
-
-export default Traces;
diff --git a/ui-pages-router/src/pages/projects/index.tsx b/ui-pages-router/src/pages/projects/index.tsx
deleted file mode 100644
index e6d892c..0000000
--- a/ui-pages-router/src/pages/projects/index.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import React from 'react';
-import { getProjects } from '@/services/projects-service';
-import AppBar from '@/components/AppBar';
-import { ProjectResponse } from '@/models/projects-response';
-import {
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableRow
-} from '@/components/ui/table';
-import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
-
-const breadcrumbItems = [
- { name: 'Home', path: '/' },
- { name: 'Projects', path: undefined },
-];
-
-interface ProjectsProps {
- projects: ProjectResponse[];
-}
-
-const Projects: React.FC = ({ projects }) => {
-
- const handleRowClick = (url: string) => {
- window.location.href = url;
- };
-
- return <>
-
-
-
-
-
-
-
- Project Name
- Traces 24h
- Traces 7d
- Traces 30d
-
-
-
- {projects.map((project, index) => (
- handleRowClick(`/projects/${project.project_name}`)}>
- {project.project_name}
- {project.tracesLast24Hours}
- {project.tracesLast7Days}
- {project.tracesLast30Days}
-
- ))}
-
-
-
-
-
- >;
-};
-
-export async function getServerSideProps() {
- return {
- props: {
- projects: await getProjects(),
- }
- };
-}
-
-
-export default Projects;
diff --git a/ui-pages-router/src/services/projects-service.ts b/ui-pages-router/src/services/projects-service.ts
deleted file mode 100644
index 46cd9a1..0000000
--- a/ui-pages-router/src/services/projects-service.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import config from '@/lib/utils/config';
-import { ProjectResponse } from '@/models/projects-response';
-
-export async function getProjects(): Promise {
- try {
- const response = await fetch(`${config.langtraceApiUrl}/langtrace/api/projects`);
-
- if (!response.ok) {
- throw new Error('Network response was not ok');
- }
- const data = await response.json();
-
- return data as ProjectResponse[];
- } catch (error) {
- console.error('Error:', error);
- throw error;
- }
-}
diff --git a/ui-pages-router/src/services/trace-service.ts b/ui-pages-router/src/services/trace-service.ts
deleted file mode 100644
index d3e6862..0000000
--- a/ui-pages-router/src/services/trace-service.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { TracesResponse } from '@/models/traces-response';
-import config from '@/lib/utils/config';
-import { buildTreeFromObject } from '@/lib/utils/build-tree-from-object';
-import { TraceTreeNode } from '@/models/trace-detail-response';
-
-export async function getTraces(
- projectId: string,
- startDate?: string,
- endDate?: string,
- feedbackFilters?: string
-): Promise {
- let url = `${config.langtraceApiUrl}/langtrace/api/projects/${projectId}/traces`;
- const queryParams = new URLSearchParams();
- if (startDate && startDate.trim() !== '') {
- queryParams.append('startDate', startDate);
- }
- if (endDate && endDate.trim() !== '') {
- queryParams.append('endDate', endDate);
- }
-
- if (feedbackFilters) {
- try {
- const filters = JSON.parse(feedbackFilters);
- if (typeof filters === 'object' && filters !== null) {
- Object.entries(filters).forEach(([key, values]) => {
- if (Array.isArray(values)) {
- values.forEach(value => {
- if (typeof value === 'string') {
- queryParams.append(`feedbackFilter[${key}][]`, value);
- }
- });
- }
- });
- }
- } catch (error) {
- console.error('Failed to parse feedbackFilters', error);
- }
- }
-
-
- if (queryParams.toString()) {
- url += `?${queryParams.toString()}`;
- }
-
- const response = await fetch(url);
- if (!response.ok) {
- throw new Error('Network response was not ok');
- }
-
- const data = await response.json();
- return data as TracesResponse;
-}
-
-
-export async function getTraceTree(projectId: string, traceId: string): Promise {
- const response = await fetch(
- `${config.langtraceApiUrl}/langtrace/api/projects/${projectId}/traces/tree/${traceId}`
- );
-
- if (!response.ok) {
- throw new Error('Network response was not ok');
- }
- const data = await response.json();
-
- return buildTreeFromObject(data as TraceTreeNode);
-}
diff --git a/ui-pages-router/src/styles/globals.css b/ui-pages-router/src/styles/globals.css
deleted file mode 100644
index 67c325e..0000000
--- a/ui-pages-router/src/styles/globals.css
+++ /dev/null
@@ -1,61 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-@layer base {
- :root {
- --background: 0 0% 100%;
- --foreground: 240 10% 3.9%;
- --card: 0 0% 100%;
- --card-foreground: 240 10% 3.9%;
- --popover: 0 0% 100%;
- --popover-foreground: 240 10% 3.9%;
- --primary: 240 5.9% 10%;
- --primary-foreground: 0 0% 98%;
- --secondary: 240 4.8% 95.9%;
- --secondary-foreground: 240 5.9% 10%;
- --muted: 240 4.8% 95.9%;
- --muted-foreground: 240 3.8% 46.1%;
- --accent: 240 4.8% 95.9%;
- --accent-foreground: 240 5.9% 10%;
- --destructive: 0 84.2% 60.2%;
- --destructive-foreground: 0 0% 98%;
- --border: 240 5.9% 90%;
- --input: 240 5.9% 90%;
- --ring: 240 5.9% 10%;
- --radius: 0.5rem;
- }
-
- .dark {
- --background: 240 10% 3.9%;
- --foreground: 0 0% 98%;
- --card: 240 10% 3.9%;
- --card-foreground: 0 0% 98%;
- --popover: 240 10% 3.9%;
- --popover-foreground: 0 0% 98%;
- --primary: 0 0% 98%;
- --primary-foreground: 240 5.9% 10%;
- --secondary: 240 3.7% 15.9%;
- --secondary-foreground: 0 0% 98%;
- --muted: 240 3.7% 15.9%;
- --muted-foreground: 240 5% 64.9%;
- --accent: 240 3.7% 15.9%;
- --accent-foreground: 0 0% 98%;
- --destructive: 0 62.8% 30.6%;
- --destructive-foreground: 0 0% 98%;
- --border: 240 3.7% 15.9%;
- --input: 240 3.7% 15.9%;
- --ring: 240 4.9% 83.9%;
- }
-}
-
-
-
-@layer base {
- * {
- @apply border-border;
- }
- body {
- @apply bg-background text-foreground;
- }
-}
diff --git a/ui-pages-router/src/styles/globals.scss b/ui-pages-router/src/styles/globals.scss
deleted file mode 100644
index 331da96..0000000
--- a/ui-pages-router/src/styles/globals.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-
-html, body {
- font-family: 'Ubuntu', 'Open Sans', sans-serif;
- margin: 0;
-}
-
-body {
- padding: 0;
-}
-
-h1, h2 {
- line-height: 0;
- padding-bottom: 6px;
-}
diff --git a/ui-pages-router/tailwind.config.ts b/ui-pages-router/tailwind.config.ts
deleted file mode 100644
index 98506a3..0000000
--- a/ui-pages-router/tailwind.config.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import type { Config } from 'tailwindcss';
-
-const config = {
- darkMode: ['class'],
- content: [
- './src/pages/**/*.{ts,tsx}',
- './src/components/**/*.{ts,tsx}',
- ],
- prefix: '',
- theme: {
- container: {
- center: true,
- padding: '2rem',
- screens: {
- '2xl': '1400px',
- },
- },
- extend: {
- colors: {
- border: 'hsl(var(--border))',
- input: 'hsl(var(--input))',
- ring: 'hsl(var(--ring))',
- background: 'hsl(var(--background))',
- foreground: 'hsl(var(--foreground))',
- primary: {
- DEFAULT: 'hsl(var(--primary))',
- foreground: 'hsl(var(--primary-foreground))',
- },
- secondary: {
- DEFAULT: 'hsl(var(--secondary))',
- foreground: 'hsl(var(--secondary-foreground))',
- },
- destructive: {
- DEFAULT: 'hsl(var(--destructive))',
- foreground: 'hsl(var(--destructive-foreground))',
- },
- muted: {
- DEFAULT: 'hsl(var(--muted))',
- foreground: 'hsl(var(--muted-foreground))',
- },
- accent: {
- DEFAULT: 'hsl(var(--accent))',
- foreground: 'hsl(var(--accent-foreground))',
- },
- popover: {
- DEFAULT: 'hsl(var(--popover))',
- foreground: 'hsl(var(--popover-foreground))',
- },
- card: {
- DEFAULT: 'hsl(var(--card))',
- foreground: 'hsl(var(--card-foreground))',
- },
- },
- borderRadius: {
- lg: 'var(--radius)',
- md: 'calc(var(--radius) - 2px)',
- sm: 'calc(var(--radius) - 4px)',
- },
- keyframes: {
- 'accordion-down': {
- from: { height: '0' },
- to: { height: 'var(--radix-accordion-content-height)' },
- },
- 'accordion-up': {
- from: { height: 'var(--radix-accordion-content-height)' },
- to: { height: '0' },
- },
- },
- animation: {
- 'accordion-down': 'accordion-down 0.2s ease-out',
- 'accordion-up': 'accordion-up 0.2s ease-out',
- },
- },
- },
- plugins: [require('tailwindcss-animate')],
-} satisfies Config;
-
-export default config;
diff --git a/ui-pages-router/tsconfig.json b/ui-pages-router/tsconfig.json
deleted file mode 100644
index e59724b..0000000
--- a/ui-pages-router/tsconfig.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "compilerOptions": {
- "target": "es5",
- "lib": ["dom", "dom.iterable", "esnext"],
- "allowJs": true,
- "skipLibCheck": true,
- "strict": true,
- "noEmit": true,
- "esModuleInterop": true,
- "module": "esnext",
- "moduleResolution": "bundler",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "preserve",
- "incremental": true,
- "plugins": [
- {
- "name": "next"
- }
- ],
- "paths": {
- "@/*": ["./src/*"]
- }
- },
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
- "exclude": ["node_modules"]
-}
|