Skip to content

Commit

Permalink
Add jump to file in playgroundv2 (#1356)
Browse files Browse the repository at this point in the history
<!-- ELLIPSIS_HIDDEN -->



> [!IMPORTANT]
> Add click-to-jump functionality in playground components to navigate
to specific file locations by clicking on function or test names.
> 
>   - **Behavior**:
> - Adds click-to-jump functionality in `FunctionTestName` and
`TabularView` components, allowing users to navigate to specific file
locations by clicking on function or test names.
> - Uses `vscode.postMessage` to send `jumpToFile` command with span
details.
>   - **Atoms**:
> - Introduces `functionObjectAtom` and `testcaseObjectAtom` in
`atoms.ts` to manage function and test case data.
>   - **UI Components**:
> - Updates `FunctionTestName` to include click handlers for function
and test names.
> - Updates `TabularView` to include click handlers for test names in
the table view.
> 
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=BoundaryML%2Fbaml&utm_source=github&utm_medium=referral)<sup>
for 14c70cb. It will automatically
update as commits are pushed.</sup>

<!-- ELLIPSIS_HIDDEN -->
  • Loading branch information
aaronvg authored Jan 21, 2025
1 parent bd78c43 commit b53feec
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,34 @@ export const selectedItemAtom = atom(
},
)

export const functionObjectAtom = atomFamily((functionName: string) =>
atom((get) => {
const { functions } = get(runtimeStateAtom)
const fn = functions.find((f) => f.name === functionName)
if (!fn) {
return undefined
}
get(selectedFunctionAtom) // Update selected function atom
return fn
}),
)

export const testcaseObjectAtom = atomFamily((params: { functionName: string; testcaseName: string }) =>
atom((get) => {
const { functions } = get(runtimeStateAtom)
const fn = functions.find((f) => f.name === params.functionName)
if (!fn) {
return undefined
}
const tc = fn.test_cases.find((tc) => tc.name === params.testcaseName)
if (!tc) {
return undefined
}
get(selectedTestcaseAtom) // Update selected testcase atom
return tc
}),
)

export const updateCursorAtom = atom(
null,
(get, set, cursor: { fileName: string; fileText: string; line: number; column: number }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,54 @@
import { ChevronRight, FlaskConical, FunctionSquare } from 'lucide-react'
import { vscode } from '../vscode'
import { functionObjectAtom, testcaseObjectAtom } from './atoms'
import { useAtomValue } from 'jotai'

interface FunctionTestNameProps {
functionName: string
testName: string
selected?: boolean
}

interface StringSpan {
start: number
end: number
source_file: string
value: string
}

export const FunctionTestName: React.FC<FunctionTestNameProps> = ({ functionName, testName, selected }) => {
const fn = useAtomValue(functionObjectAtom(functionName))
const tc = useAtomValue(testcaseObjectAtom({ functionName, testcaseName: testName }))
const createSpan = (span: { start: number; end: number; file_path: string; start_line: number }) => ({
start: span.start,
end: span.end,
source_file: span.file_path,
value: `${span.file_path.split('/').pop() ?? '<file>.baml'}:${span.start_line + 1}`,
})

return (
<div className={`flex w-full items-center space-x-1 text-xs ${selected ? '' : 'text-muted-foreground'}`}>
<div className='flex items-center'>
<FunctionSquare className='mr-1 h-3 w-3' />
<div
className='flex items-center cursor-pointer hover:text-primary'
onClick={() => {
if (fn?.span) {
vscode.postMessage({ command: 'jumpToFile', span: createSpan(fn.span) })
}
}}
>
<FunctionSquare className='mr-1 w-3 h-3' />
{functionName}
</div>
<ChevronRight className='h-3 w-3' />
<div className='flex items-center'>
<FlaskConical className='mr-1 h-3 w-3' />
<ChevronRight className='w-3 h-3' />
<div
className='flex items-center cursor-pointer hover:text-primary'
onClick={() => {
if (tc?.span) {
vscode.postMessage({ command: 'jumpToFile', span: createSpan(tc.span) })
}
}}
>
<FlaskConical className='mr-1 w-3 h-3' />
{testName}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Label } from '@/components/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
import { useAtom } from 'jotai'
import { useAtom, useAtomValue } from 'jotai'
import { Check, Copy, Play } from 'lucide-react'
import * as React from 'react'

import { cn } from '@/lib/utils'
import { WasmFunctionResponse, WasmTestResponse } from '@gloo-ai/baml-schema-wasm-web'
import { ErrorBoundary } from 'react-error-boundary'
import { Button } from '~/components/ui/button'
import { selectedItemAtom, TestState } from '../../../atoms'
import { selectedItemAtom, testcaseObjectAtom, TestState } from '../../../atoms'
import { type TestHistoryRun } from '../atoms'
import { useRunTests } from '../test-runner'
import { getExplanation, getStatus, getTestStateResponse } from '../testStateUtils'
Expand All @@ -18,6 +18,7 @@ import { MarkdownRenderer } from './MarkdownRenderer'
import { ParsedResponseRenderer } from './ParsedResponseRender'
import { TestStatus } from './TestStatus'
import { ScrollArea } from '~/components/ui/scroll-area'
import { vscode } from '@/shared/baml-project-panel/vscode'
interface TabularViewProps {
currentRun: TestHistoryRun
}
Expand Down Expand Up @@ -122,6 +123,17 @@ export const TabularView: React.FC<TabularViewProps> = ({ currentRun }) => {
}))
}

const tc = useAtomValue(
testcaseObjectAtom({ functionName: selectedItem?.[0] ?? '', testcaseName: selectedItem?.[1] ?? '' }),
)

const createSpan = (span: { start: number; end: number; file_path: string; start_line: number }) => ({
start: span.start,
end: span.end,
source_file: span.file_path,
value: `${span.file_path.split('/').pop() ?? '<file>.baml'}:${span.start_line + 1}`,
})

const selectedRowRef = React.useRef<HTMLTableRowElement>(null)

React.useEffect(() => {
Expand Down Expand Up @@ -215,7 +227,14 @@ export const TabularView: React.FC<TabularViewProps> = ({ currentRun }) => {
>
<Play className='w-4 h-4 text-purple-400' />
</Button>
<span className='text-xs truncate whitespace-pre-wrap break-all text-muted-foreground'>
<span
className='text-xs truncate whitespace-pre-wrap break-all cursor-pointer text-muted-foreground hover:text-primary'
onClick={(e) => {
e.stopPropagation()
if (!tc?.span) return
vscode.postMessage({ command: 'jumpToFile', span: createSpan(tc.span) })
}}
>
{test.testName}
</span>
</div>
Expand Down

0 comments on commit b53feec

Please sign in to comment.