From 0bc0e81b4654a05a8f6bc7810e412fe3ec781ff8 Mon Sep 17 00:00:00 2001 From: Software Engineer - Frontend Date: Tue, 4 Feb 2025 16:32:11 +0500 Subject: [PATCH] issue #327 filters to logs Eliza UI sections to select run and date range --- client/src/App.tsx | 7 +- .../src/components/ui/logging/hooks/index.ts | 72 +++++++ client/src/components/ui/logging/index.tsx | 185 ++++++++++++++++++ 3 files changed, 259 insertions(+), 5 deletions(-) create mode 100644 client/src/components/ui/logging/hooks/index.ts create mode 100644 client/src/components/ui/logging/index.tsx diff --git a/client/src/App.tsx b/client/src/App.tsx index f9515ea3124..779270efbd4 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -9,7 +9,7 @@ import Chat from "./routes/chat"; import Overview from "./routes/overview"; import Home from "./routes/home"; import useVersion from "./hooks/use-version"; -import Logs from "./components/ui/logs"; +import Logs from "./components/ui/logging"; const queryClient = new QueryClient({ defaultOptions: { @@ -45,10 +45,7 @@ function App() { path="settings/:agentId" element={} /> - } - /> + } /> diff --git a/client/src/components/ui/logging/hooks/index.ts b/client/src/components/ui/logging/hooks/index.ts new file mode 100644 index 00000000000..ba0c1711ebb --- /dev/null +++ b/client/src/components/ui/logging/hooks/index.ts @@ -0,0 +1,72 @@ +import { useState } from "react"; + +export const use = () => { + const [uniqueRuns, setUniqueRuns] = useState([]); + const [traceData, setTraceData] = useState([]); + const [selectedRun, setSelectedRun] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [isRun, setIsRun] = useState(false); + + // Fetch all unique runs + const fetchUniqueRuns = async () => { + setLoading(true); + try { + const response = await fetch( + "http://localhost:4000/api/traces/unique-runs" + ); + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`); + const data = await response.json(); + setUniqueRuns(data.unique_runs || []); + } catch (err: any) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + // Fetch traces for a selected RUN ID with filters + const fetchTraceData = async ( + runId: string | null, + filters: any, + page = 1 + ) => { + if (!runId) return; + + setLoading(true); + setSelectedRun(runId); + try { + const queryParams = new URLSearchParams({ + page: page.toString(), + ...(filters.name && { name: filters.name }), + ...(filters.start_date && { start_date: filters.start_date }), + ...(filters.end_date && { end_date: filters.end_date }), + }); + + const response = await fetch( + `http://localhost:4000/api/traces/by-run/${runId}?${queryParams.toString()}` + ); + if (!response.ok) + throw new Error(`HTTP error! Status: ${response.status}`); + const data = await response.json(); + setTraceData(data.data || []); + } catch (err: any) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + return { + uniqueRuns, + traceData, + selectedRun, + loading, + error, + fetchUniqueRuns, + fetchTraceData, + isRun, + setIsRun, + }; +}; diff --git a/client/src/components/ui/logging/index.tsx b/client/src/components/ui/logging/index.tsx new file mode 100644 index 00000000000..b0c3320eba4 --- /dev/null +++ b/client/src/components/ui/logging/index.tsx @@ -0,0 +1,185 @@ +import { useEffect, useState } from "react"; +import { Label } from "../label"; +import { use } from "./hooks"; + +function Logs() { + const { + uniqueRuns, + traceData, + selectedRun, + loading, + error, + fetchUniqueRuns, + fetchTraceData, + isRun, + setIsRun, + } = use(); + + // Get today's date in YYYY-MM-DD format + const today = new Date().toISOString().split("T")[0]; + + // State for filters (default start_date and end_date to today) + const [filters, setFilters] = useState({ + name: "", + start_date: today, + end_date: today, + }); + + useEffect(() => { + fetchUniqueRuns(); + }, []); + + return ( +
+ {/* Filter Section at the Top */} +
+ +
+ + setFilters({ ...filters, name: e.target.value }) + } + /> + + setFilters({ + ...filters, + start_date: e.target.value, + }) + } + /> + + setFilters({ ...filters, end_date: e.target.value }) + } + /> + +
+
+ +
+ {/* Left: Unique Runs List (Scrollable) */} +
+ + + {loading && ( +
+
+
+ )} + + {error && ( +
+ ❌ Error: {error} +
+ )} + +
+ {uniqueRuns.map((run, index) => ( +
{ + setIsRun(true); + fetchTraceData(run, filters); + }} + className={`p-4 bg-gray-800 rounded-lg shadow-md hover:shadow-xl transition duration-300 cursor-pointer ${ + selectedRun === run + ? "border-2 border-blue-500" + : "" + }`} + > +

{run}

+
+ ))} +
+
+ + {/* Right: Trace Details (Scrollable) */} + {isRun && ( +
+ + + {loading && ( +

Loading traces...

+ )} + + {traceData.length > 0 ? ( +
    + {traceData.map((trace, index) => ( +
  • +

    + ID:{" "} + + {trace.id} + +

    +

    + Run:{" "} + + {trace.run} + +

    +

    + Time:{" "} + + {trace.time} + +

    +

    + Name:{" "} + + {trace.name} + +

    +

    + Data: +

    +
    +                                            {JSON.stringify(
    +                                                trace.data,
    +                                                null,
    +                                                2
    +                                            )}
    +                                        
    +
  • + ))} +
+ ) : selectedRun && !loading ? ( +

+ No trace data available. +

+ ) : null} +
+ )} +
+
+ ); +} + +export default Logs;