@@ -54,6 +54,7 @@ import { api } from '@/lib/api';
5454import { ScrollArea } from '@/components/ui/scroll-area' ;
5555import { Badge } from '@/components/ui/badge' ;
5656import { Slider } from '@/components/ui/slider' ;
57+ import { useToast } from '@/hooks/use-toast' ;
5758
5859const formatBytes = ( bytes : number , decimals = 2 ) => {
5960 if ( ! bytes && bytes !== 0 ) return 'N/A' ;
@@ -115,6 +116,7 @@ export default function BuildComparisonPage() {
115116 ) ;
116117
117118 const [ mounted , setMounted ] = useState ( false ) ;
119+ const { toast } = useToast ( ) ;
118120 useEffect ( ( ) => setMounted ( true ) , [ ] ) ;
119121
120122 // Debounce maxDataPoints changes
@@ -159,7 +161,13 @@ export default function BuildComparisonPage() {
159161 setSelectedBinaries ( [ binariesData [ 0 ] . id , binariesData [ 1 ] . id ] ) ;
160162 }
161163 } catch ( err ) {
162- setError ( err instanceof Error ? err . message : 'Failed to load data' ) ;
164+ const errorMessage = err instanceof Error ? err . message : 'Failed to load data' ;
165+ setError ( errorMessage ) ;
166+ toast ( {
167+ title : 'Error' ,
168+ description : errorMessage ,
169+ variant : 'destructive' ,
170+ } ) ;
163171 } finally {
164172 setLoading ( false ) ;
165173 }
@@ -209,6 +217,11 @@ export default function BuildComparisonPage() {
209217 }
210218 } catch ( err ) {
211219 console . error ( 'Failed to load benchmark data:' , err ) ;
220+ toast ( {
221+ title : 'Error' ,
222+ description : 'Failed to load benchmark names' ,
223+ variant : 'destructive' ,
224+ } ) ;
212225 } finally {
213226 setDataProcessing ( false ) ;
214227 }
@@ -240,12 +253,22 @@ export default function BuildComparisonPage() {
240253
241254 setDataProcessing ( true ) ;
242255 try {
256+ const versionOption = pythonVersionOptions . find (
257+ ( v ) => v . label === selectedPythonVersionKey
258+ ) ;
259+ if ( ! versionOption ) {
260+ setDataProcessing ( false ) ;
261+ return ;
262+ }
263+
243264 // Create batch request for ALL benchmarks and selected binaries (load everything upfront)
244265 const trendQueries = allBenchmarkNames . flatMap ( ( benchmark ) =>
245266 selectedBinaries . map ( ( binaryId ) => ( {
246267 benchmark_name : benchmark ,
247268 binary_id : binaryId ,
248269 environment_id : selectedEnvironmentId ,
270+ python_major : versionOption . major ,
271+ python_minor : versionOption . minor ,
249272 limit : debouncedMaxDataPoints ,
250273 } ) )
251274 ) ;
@@ -267,6 +290,11 @@ export default function BuildComparisonPage() {
267290 setTrendData ( newTrendData ) ; // Replace entirely since we're loading all data
268291 } catch ( err ) {
269292 console . error ( 'Failed to load trend data:' , err ) ;
293+ toast ( {
294+ title : 'Error' ,
295+ description : 'Failed to load trend data' ,
296+ variant : 'destructive' ,
297+ } ) ;
270298 } finally {
271299 setDataProcessing ( false ) ;
272300 }
@@ -276,6 +304,8 @@ export default function BuildComparisonPage() {
276304 } , [
277305 selectedBinaries ,
278306 selectedEnvironmentId ,
307+ selectedPythonVersionKey ,
308+ pythonVersionOptions ,
279309 allBenchmarkNames ,
280310 debouncedMaxDataPoints ,
281311 ] ) ; // Remove selectedBenchmarks and benchmarkMode from dependencies
@@ -758,7 +788,11 @@ export default function BuildComparisonPage() {
758788 } )
759789 . catch ( ( error ) => {
760790 console . error ( 'Failed to export chart as PNG:' , error ) ;
761- alert ( 'PNG export failed. Please try again.' ) ;
791+ toast ( {
792+ title : 'Export Error' ,
793+ description : 'PNG export failed. Please try again.' ,
794+ variant : 'destructive' ,
795+ } ) ;
762796 } ) ;
763797 } ;
764798
@@ -1284,23 +1318,30 @@ export default function BuildComparisonPage() {
12841318 formatter = { ( value : number , name : string , props ) => {
12851319 const binary = binaries . find ( ( b ) => b . id === name ) ;
12861320 const displayName = binary ?. name || name ;
1321+ const fullVersion = props . payload . fullVersion
1322+ ? `(py ${ props . payload . fullVersion } )`
1323+ : '' ;
12871324
12881325 if ( viewMode === 'relative' ) {
1289- return [ `${ value . toFixed ( 2 ) } %` , displayName ] ;
1326+ return [ `${ value . toFixed ( 2 ) } % ${ fullVersion } ` , displayName ] ;
12901327 } else {
1291- return [ formatBytes ( value ) , displayName ] ;
1328+ return [ ` ${ formatBytes ( value ) } ${ fullVersion } ` , displayName ] ;
12921329 }
12931330 } }
12941331 labelFormatter = { ( label , payload ) => {
12951332 const commitData = payload ?. [ 0 ] ?. payload ;
1296- if ( commitData ) {
1297- const message = commitData . commitMessage || 'No message' ;
1298- return `${ commitData . commitSha } : ${ message . substring (
1299- 0 ,
1300- 50
1301- ) } ${ message . length > 50 ? '...' : '' } `;
1333+ if ( commitData && commitData . commitSha && commitData . fullVersion ) {
1334+ const message = commitData . commitMessage ;
1335+ if ( message && message . trim ( ) ) {
1336+ const truncatedMessage = message . length > 50
1337+ ? `${ message . substring ( 0 , 50 ) } ...`
1338+ : message ;
1339+ return `${ commitData . commitSha } (py ${ commitData . fullVersion } ): ${ truncatedMessage } ` ;
1340+ } else {
1341+ return `${ commitData . commitSha } (py ${ commitData . fullVersion } )` ;
1342+ }
13021343 }
1303- return label ;
1344+ return label || 'No data' ;
13041345 } }
13051346 contentStyle = { {
13061347 backgroundColor : 'hsl(var(--background))' ,
0 commit comments