Skip to content

Commit

Permalink
Document logs history parameters tab in Playground (#592)
Browse files Browse the repository at this point in the history
  • Loading branch information
andresgutgon authored Nov 14, 2024
1 parent 65aa16e commit fa267d4
Show file tree
Hide file tree
Showing 27 changed files with 596 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { PinnedDocumentation } from '../components/PinnedDocumentation'

export const useVariablesData = (providerLog: ProviderLogDto) => {
const [config, setConfig] = useState<Config>()
const { data: documentLogWithMetadata } = useDocumentLogWithMetadata(
providerLog.documentLogUuid,
)
const { data: documentLogWithMetadata } = useDocumentLogWithMetadata({
documentLogUuid: providerLog.documentLogUuid,
})
const [isMessagesPinned, setIsMessagesPinned] = useState(false)
const [isPopoverOpen, setIsPopoverOpen] = useState(false)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ export default function Playground({
const { data: providerLog } = useProviderLog(
providerLogId ? Number(providerLogId) : undefined,
)
const { data: documentLogWithMetadata } = useDocumentLogWithMetadata(
providerLog?.documentLogUuid,
)
const { data: documentLogWithMetadata } = useDocumentLogWithMetadata({
documentLogUuid: providerLog?.documentLogUuid,
})
const parameters = useMemo(() => {
if (!providerLog || !documentLogWithMetadata) {
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,11 @@
import {
Button,
cn,
ReactStateDispatch,
Select,
Text,
} from '@latitude-data/web-ui'
import { cn, ReactStateDispatch, Select } from '@latitude-data/web-ui'
import { PlaygroundInputs } from '$/hooks/useDocumentParameters'

import { ParamsSource } from '../index'
import { ParametersPaginationNav } from '../PaginationNav'
import { InputMapper } from './InputsMapper'
import { type UseSelectDataset } from './useSelectDataset'

const INDEX_ZERO_LIST = 1
function DatasetRowsPagination({
currentIndex,
totalCount,
onRowChange,
}: {
currentIndex: number | undefined
totalCount: number | undefined
onRowChange: (index: number) => void
}) {
if (currentIndex === undefined || totalCount === undefined) return null

return (
<div className='flex items-center'>
<Button
size='default'
variant='ghost'
disabled={currentIndex <= 0}
iconProps={{
name: 'chevronLeft',
}}
onClick={() => onRowChange(currentIndex - 1)}
/>
<div className='flex flex-row items-center gap-x-1'>
<Text.H5M color='foregroundMuted'>
{currentIndex + INDEX_ZERO_LIST}
</Text.H5M>
<div className='max-w-14' />
<Text.H5M color='foregroundMuted'>
of {totalCount} rows in dataset
</Text.H5M>
</div>
<Button
size='default'
variant='ghost'
disabled={currentIndex >= totalCount - INDEX_ZERO_LIST}
iconProps={{
name: 'chevronRight',
}}
onClick={() => onRowChange(currentIndex + 1)}
/>
</div>
)
}

export function DatasetParams({
inputs,
datasetInfo: data,
Expand All @@ -68,9 +18,11 @@ export function DatasetParams({
const selectedId = data.selectedDataset?.id
? String(data.selectedDataset.id)
: undefined
const onPrevPage = (page: number) => data.onRowChange(page - 1)
const onNextPage = (page: number) => data.onRowChange(page + 1)
return (
<div className='flex flex-col gap-y-4'>
<div className='flex flex-row items-center justify-between gap-x-4'>
<div className='flex flex-row items-center justify-between gap-x-4 border-b border-border pb-2'>
<Select
name='datasetId'
placeholder={data.isLoading ? 'Loading...' : 'Select dataset'}
Expand All @@ -80,10 +32,13 @@ export function DatasetParams({
value={selectedId}
/>
<div className='flex-none'>
<DatasetRowsPagination
<ParametersPaginationNav
zeroIndex
currentIndex={data.selectedRowIndex}
totalCount={data.totalRows}
onRowChange={data.onRowChange}
onPrevPage={onPrevPage}
onNextPage={onNextPage}
label='rows in dataset'
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,104 @@
import { DocumentLogWithMetadataAndError } from '@latitude-data/core/repositories'
import { Badge, cn, Icon, Skeleton, Text, Tooltip } from '@latitude-data/web-ui'
import {
PlaygroundInput,
PlaygroundInputs,
} from '$/hooks/useDocumentParameters'
import { useGenerateDocumentLogDetailUrl } from '$/hooks/useGenerateDocumentLogDetailUrl'
import { format } from 'date-fns'
import Link from 'next/link'

import { InputParams } from '../Input'
import { ParametersPaginationNav } from '../PaginationNav'
import { useLogHistoryParams } from './useLogHistoryParams'

function usePaginatedDocumentLogUrl({
page,
selectedLog,
isLoading,
}: {
selectedLog: DocumentLogWithMetadataAndError | undefined
page: number | undefined
isLoading: boolean
}) {
const uuid = selectedLog?.uuid
const { url } = useGenerateDocumentLogDetailUrl({
page,
documentLogUuid: uuid,
})

if (isLoading || !uuid || !url) return undefined

const shortCode = uuid.split('-')[0]
const createdAt = format(selectedLog.createdAt, 'PPp')
return {
url,
shortCode,
createdAt,
hasError: !!selectedLog.error.message,
}
}

export function HistoryLogParams({
inputs: _inputs,
setInput: _setInput,
inputs,
setInput,
setInputs,
}: {
inputs: PlaygroundInputs
setInput: (param: string, value: PlaygroundInput) => void
setInputs: (newInputs: PlaygroundInputs) => void
}) {
return <div>TODO: DatasetParams</div>
const data = useLogHistoryParams({ inputs, setInputs })
const urlData = usePaginatedDocumentLogUrl({
selectedLog: data.selectedLog,
page: data.page,
isLoading: data.isLoadingLog,
})
return (
<div className='flex flex-col gap-y-4'>
<div className='flex flex-row gap-x-4 justify-between items-center border-border border-b pb-2'>
<div className='flex-grow'>
{data.isLoadingLog ? (
<div className='flex flex-row gap-x-2 w-full'>
<Skeleton height='h3' className='w-2/3' />
<Skeleton height='h3' className='w-1/3' />
</div>
) : null}
{!data.isLoadingLog && urlData ? (
<Link href={urlData.url}>
<div className='flex flex-row items-center gap-x-2'>
<Text.H5>{urlData.createdAt}</Text.H5>
{urlData.hasError ? (
<Tooltip
variant='destructive'
trigger={
<Badge variant='destructive'>{urlData.shortCode}</Badge>
}
>
This log has an error
</Tooltip>
) : (
<Badge variant='accent'>{urlData.shortCode}</Badge>
)}
<Icon name='externalLink' color='foregroundMuted' />
</div>
</Link>
) : null}
</div>
<div>
<ParametersPaginationNav
disabled={data.isLoadingLog}
label='history logs'
currentIndex={data.position}
totalCount={data.count}
onPrevPage={data.onPrevPage}
onNextPage={data.onNextPage}
/>
</div>
</div>
<div className={cn({ 'opacity-50': data.isLoading })}>
<InputParams inputs={inputs} setInput={setInput} />
</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { useCallback, useState } from 'react'

import { DocumentLog } from '@latitude-data/core/browser'
import { useCurrentCommit, useCurrentProject } from '@latitude-data/web-ui'
import { useCurrentDocument } from '$/app/providers/DocumentProvider'
import { PlaygroundInputs } from '$/hooks/useDocumentParameters'
import useDocumentLogs from '$/stores/documentLogs'
import useDocumentLogWithPaginationPosition, {
LogWithPosition,
} from '$/stores/documentLogWithPaginationPosition'
import useDocumentLogsPagination from '$/stores/useDocumentLogsPagination'

import { useSelectedLogRow } from './useSelectedRow'

function getValue({ paramValue }: { paramValue: unknown | undefined }) {
try {
const value = JSON.stringify(paramValue)
return { value, includedInPrompt: paramValue !== undefined }
} catch {
return { value: '', includedInPrompt: false }
}
}

function mapLogParametersToInputs({
inputs,
parameters,
}: {
inputs: PlaygroundInputs
parameters: DocumentLog['parameters'] | undefined
}): PlaygroundInputs | undefined {
const params = parameters ?? {}
// No parameters
if (!Object.keys(params).length) return undefined

return Object.entries(inputs).reduce((acc, [key]) => {
acc[key] = getValue({ paramValue: params[key] })
return acc
}, {} as PlaygroundInputs)
}

const ONLY_ONE_PAGE = '1'
export function useLogHistoryParams({
inputs,
setInputs,
}: {
inputs: PlaygroundInputs
setInputs: (newInputs: PlaygroundInputs) => void
}) {
const document = useCurrentDocument()
const { saveRowInfo, selectedRow } = useSelectedLogRow({ document })
const selectedLogUuid = selectedRow?.documentLogUuid
const { project } = useCurrentProject()
const { commit } = useCurrentCommit()
const { data: pagination, isLoading: isLoadingCounter } =
useDocumentLogsPagination({
projectId: project.id,
commitUuid: commit.uuid,
documentUuid: document.documentUuid,
page: '1', // Not used really. This is only for the counter.
pageSize: ONLY_ONE_PAGE,
})

const [position, setPosition] = useState<LogWithPosition | undefined>(
selectedLogUuid ? undefined : { position: 1, page: 1 },
)
const onFetchCurrentLog = useCallback(
(data: LogWithPosition) => {
setPosition(data)
},
[selectedLogUuid],
)
const { isLoading: isLoadingPosition } = useDocumentLogWithPaginationPosition(
{
documentLogUuid: selectedLogUuid,
onFetched: onFetchCurrentLog,
},
)

const { data: logs, isLoading: isLoadingLog } = useDocumentLogs({
documentUuid: position === undefined ? undefined : document.documentUuid,
commitUuid: commit.uuid,
projectId: project.id,
page: position === undefined ? undefined : String(position.position),
pageSize: ONLY_ONE_PAGE,
onFetched: (logs) => {
const log = logs[0]
if (!log) return

const newInputs = mapLogParametersToInputs({
inputs,
parameters: log.parameters,
})

if (!newInputs) return

setInputs(newInputs)
saveRowInfo({ documentLogUuid: log.uuid })
},
})

const updatePosition = useCallback((position: number) => {
setPosition((prev) =>
prev ? { ...prev, position } : { position, page: 1 },
)
}, [])

const onNextPage = useCallback(
(position: number) => updatePosition(position + 1),
[updatePosition],
)

const onPrevPage = useCallback(
(position: number) => updatePosition(position - 1),
[updatePosition],
)

const isLoading = isLoadingLog || isLoadingCounter
const log = logs?.[0]
return {
selectedLog: log,
isLoadingLog: isLoadingPosition || isLoadingLog,
isLoading,
page: position?.page,
position: position?.position,
count: pagination?.count ?? 0,
onNextPage,
onPrevPage,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useCallback } from 'react'

import { DocumentVersion } from '@latitude-data/core/browser'
import { AppLocalStorage, useLocalStorage } from '@latitude-data/web-ui'

export type SelectedLogRow = {
documentLogUuid: string | undefined
}

type SelectedRowByDocumentDataset = Record<string, SelectedLogRow>
export function useSelectedLogRow({ document }: { document: DocumentVersion }) {
const key = `${document.documentUuid}:documentLogUuid`
const { value: allValues, setValue } =
useLocalStorage<SelectedRowByDocumentDataset>({
key: AppLocalStorage.playgroundParamsSelectedLogRow,
defaultValue: {},
})

const saveRowInfo = useCallback(
({ documentLogUuid }: SelectedLogRow) => {
setValue((prev) => {
return {
...prev,
[key]: { documentLogUuid },
}
})
},
[allValues, key, setValue],
)

const selectedRow = allValues[key]
return {
selectedRow,
saveRowInfo,
}
}
Loading

0 comments on commit fa267d4

Please sign in to comment.