Skip to content

Commit

Permalink
Merge pull request #2167 from Agenta-AI/fix/moving-filter-states-in-c…
Browse files Browse the repository at this point in the history
…ontextapi

fix(frontend): moved all the query states in the context-api
  • Loading branch information
bekossy authored Nov 3, 2024
2 parents 8684e40 + 726a899 commit 416450b
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 52 deletions.
95 changes: 89 additions & 6 deletions agenta-web/src/contexts/observability.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,45 @@ import {
} from "@/services/observability/types"
import React, {createContext, PropsWithChildren, useContext, useEffect, useState} from "react"
import {useRouter} from "next/router"
import {SortResult} from "@/components/Filters/Sort"
import {Filter} from "@/lib/Types"

type ObservabilityContextType = {
traces: _AgentaRootsResponse[]
count: number
isLoading: boolean
fetchTraces: (queries?: string) => void
fetchTraces: () => void
clearQueryStates: () => void
searchQuery: string
setSearchQuery: React.Dispatch<React.SetStateAction<string>>
traceTabs: TraceTabTypes
setTraceTabs: React.Dispatch<React.SetStateAction<TraceTabTypes>>
filters: Filter[]
setFilters: React.Dispatch<React.SetStateAction<Filter[]>>
sort: SortResult
setSort: React.Dispatch<React.SetStateAction<SortResult>>
pagination: {page: number; size: number}
setPagination: React.Dispatch<React.SetStateAction<{page: number; size: number}>>
}

type TraceTabTypes = "tree" | "node" | "chat"

const initialValues: ObservabilityContextType = {
traces: [],
count: 0,
isLoading: false,
fetchTraces: () => {},
clearQueryStates: () => {},
searchQuery: "",
setSearchQuery: () => {},
traceTabs: "tree",
setTraceTabs: () => {},
filters: [],
setFilters: () => {},
sort: {type: "standard", sorted: ""},
setSort: () => {},
pagination: {page: 1, size: 10},
setPagination: () => {},
}

export const ObservabilityContext = createContext<ObservabilityContextType>(initialValues)
Expand All @@ -37,11 +63,20 @@ const ObservabilityContextProvider: React.FC<PropsWithChildren> = ({children}) =
const [traces, setTraces] = useState<_AgentaRootsResponse[]>([])
const [traceCount, setTraceCount] = useState(0)
const [isLoading, setIsLoading] = useState(true)

const fetchTraces = async (queries?: string) => {
// query states
const [searchQuery, setSearchQuery] = useState("")
const [traceTabs, setTraceTabs] = useState<TraceTabTypes>("tree")
const [filters, setFilters] = useState<Filter[]>([])
const [sort, setSort] = useState<SortResult>({} as SortResult)
const [pagination, setPagination] = useState({page: 1, size: 10})

const fetchTraces = async () => {
try {
setIsLoading(true)
const data = await fetchAllTraces({appId, queries: queries || ""})

const queries = generateTraceQueryString()

const data = await fetchAllTraces(queries)

const transformedTraces: _AgentaRootsResponse[] = []

Expand Down Expand Up @@ -77,11 +112,48 @@ const ObservabilityContextProvider: React.FC<PropsWithChildren> = ({children}) =
}
}

const generateTraceQueryString = () => {
const params: Record<string, any> = {
size: pagination.size,
page: pagination.page,
focus: traceTabs === "chat" ? "node" : traceTabs,
}

if (appId) {
params.filtering = JSON.stringify({
conditions: [{key: "refs.application.id", operator: "is", value: appId}],
})
}

if (filters.length > 0) {
params.filtering = JSON.stringify({conditions: filters})
}

if (sort) {
if (sort.type === "standard") {
params.oldest = sort.sorted
} else if (sort.type === "custom" && sort.customRange?.startTime) {
params.oldest = sort.customRange.startTime
params.newest = sort.customRange.endTime
}
}

return params
}

const clearQueryStates = () => {
setSearchQuery("")
setTraceTabs("tree")
setFilters([])
setSort({} as SortResult)
setPagination({page: 1, size: 10})
}

useEffect(() => {
if (appId) {
fetchTraces("&focus=tree&size=10&page=1")
fetchTraces()
}
}, [appId])
}, [appId, filters, traceTabs, sort, pagination])

observabilityContextValues.traces = traces
observabilityContextValues.isLoading = isLoading
Expand All @@ -95,6 +167,17 @@ const ObservabilityContextProvider: React.FC<PropsWithChildren> = ({children}) =
isLoading,
fetchTraces,
count: traceCount || 0,
clearQueryStates,
searchQuery,
setSearchQuery,
traceTabs,
setTraceTabs,
filters,
setFilters,
sort,
setSort,
pagination,
setPagination,
}}
>
{children}
Expand Down
64 changes: 24 additions & 40 deletions agenta-web/src/pages/apps/[app_id]/observability/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,28 @@ const useStyles = createUseStyles((theme: JSSTheme) => ({

interface Props {}

type TraceTabTypes = "tree" | "node" | "chat"

const ObservabilityDashboard = ({}: Props) => {
const {traces, isLoading, count, fetchTraces} = useObservabilityData()
const {
traces,
isLoading,
count,
searchQuery,
setSearchQuery,
traceTabs,
setTraceTabs,
filters,
setFilters,
sort,
setSort,
pagination,
setPagination,
} = useObservabilityData()
const appId = useAppId()
const router = useRouter()
const classes = useStyles()
const [selectedTraceId, setSelectedTraceId] = useQueryParam("trace", "")
const [searchQuery, setSearchQuery] = useState("")
const [traceTabs, setTraceTabs] = useState<TraceTabTypes>("tree")
const [editColumns, setEditColumns] = useState<string[]>(["span_type"])
const [filters, setFilters] = useState<Filter[]>([])
const [sort, setSort] = useState<SortResult>({} as SortResult)
const [isFilterColsDropdownOpen, setIsFilterColsDropdownOpen] = useState(false)
const [pagination, setPagination] = useState({current: 1, page: 10})
const [columns, setColumns] = useState<ColumnsType<_AgentaRootsResponse>>([
{
title: "ID",
Expand Down Expand Up @@ -385,8 +392,14 @@ const ObservabilityDashboard = ({}: Props) => {
}

const onPaginationChange = (current: number, pageSize: number) => {
setPagination({current, page: pageSize})
setPagination({size: pageSize, page: current})
}
// reset pagination to page 1 whenever quearies get updated
useUpdateEffect(() => {
if (pagination.page > 1) {
setPagination({...pagination, page: 1})
}
}, [filters, sort, traceTabs])

const onSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const query = e.target.value
Expand Down Expand Up @@ -443,9 +456,6 @@ const ObservabilityDashboard = ({}: Props) => {
setFilters((prevFilters) => prevFilters.filter((f) => f.key !== "node.type"))
}
}
if (pagination.current > 1) {
setPagination({...pagination, current: 1})
}
}
// Sync traceTabs with filters state
useUpdateEffect(() => {
Expand All @@ -459,32 +469,6 @@ const ObservabilityDashboard = ({}: Props) => {
setSort({type, sorted, customRange})
}, [])

const fetchFilterdTrace = async () => {
const focusPoint = traceTabs == "chat" ? "focus=node" : `focus=${traceTabs}`
const filterQuery = filters[0]?.operator
? `&filtering={"conditions":${JSON.stringify(filters)}}`
: ""
const paginationQuery = `&size=${pagination.page}&page=${pagination.current}`

let sortQuery = ""
if (sort) {
sortQuery =
sort.type === "standard"
? `&oldest=${sort.sorted}`
: sort.type === "custom" && sort.customRange?.startTime
? `&oldest=${sort.customRange.startTime}&newest=${sort.customRange.endTime}`
: ""
}

const data = await fetchTraces(`&${focusPoint}${paginationQuery}${sortQuery}${filterQuery}`)

return data
}

useUpdateEffect(() => {
fetchFilterdTrace()
}, [filters, traceTabs, sort, pagination])

return (
<div className="flex flex-col gap-6">
<Typography.Text className={classes.title}>Observability</Typography.Text>
Expand Down Expand Up @@ -596,8 +580,8 @@ const ObservabilityDashboard = ({}: Props) => {
total={count}
align="end"
className={classes.pagination}
current={pagination.current}
pageSize={pagination.page}
current={pagination.page}
pageSize={pagination.size}
onChange={onPaginationChange}
/>
</div>
Expand Down
8 changes: 2 additions & 6 deletions agenta-web/src/services/observability/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@ import axios from "@/lib/helpers/axiosConfig"
// - update: PUT data to server
// - delete: DELETE data from server

export const fetchAllTraces = async ({appId, queries}: {appId: string; queries?: string}) => {
const filterByAppId = `filtering={"conditions":[{"key":"refs.application.id","operator":"is","value":"${appId}"}]}`

const response = await axios.get(
`${getAgentaApiUrl()}/api/observability/v1/traces?${filterByAppId}${queries}`,
)
export const fetchAllTraces = async (params = {}) => {
const response = await axios.get(`${getAgentaApiUrl()}/api/observability/v1/traces`, {params})
return response.data
}

Expand Down

0 comments on commit 416450b

Please sign in to comment.