@@ -72,6 +72,7 @@ export class ProcessViewerViewModel implements ViewModel {
7272 errorAtom : jotai . PrimitiveAtom < string > ;
7373 lastSuccessAtom : jotai . PrimitiveAtom < number > ;
7474 pausedAtom : jotai . PrimitiveAtom < boolean > ;
75+ selectedPidAtom : jotai . PrimitiveAtom < number > ;
7576
7677 connection : jotai . Atom < string > ;
7778 connStatus : jotai . Atom < ConnStatus > ;
@@ -93,6 +94,7 @@ export class ProcessViewerViewModel implements ViewModel {
9394 this . errorAtom = jotai . atom < string > ( null ) as jotai . PrimitiveAtom < string > ;
9495 this . lastSuccessAtom = jotai . atom < number > ( 0 ) as jotai . PrimitiveAtom < number > ;
9596 this . pausedAtom = jotai . atom < boolean > ( false ) as jotai . PrimitiveAtom < boolean > ;
97+ this . selectedPidAtom = jotai . atom < number > ( null ) as jotai . PrimitiveAtom < number > ;
9698
9799 this . connection = jotai . atom ( ( get ) => {
98100 const connValue = get ( this . env . getBlockMetaKeyAtom ( blockId , "connection" ) ) ;
@@ -372,32 +374,37 @@ const ProcessRow = React.memo(function ProcessRow({
372374 proc,
373375 hasCpu,
374376 platform,
377+ selected,
378+ onSelect,
375379} : {
376380 proc : ProcessInfo ;
377381 hasCpu : boolean ;
378382 platform : string ;
383+ selected : boolean ;
384+ onSelect : ( pid : number ) => void ;
379385} ) {
380386 const gridTemplate = getGridTemplate ( platform ) ;
381387 const showStatus = platform !== "windows" && platform !== "darwin" ;
382388 const showThreads = platform !== "windows" ;
383389 return (
384390 < div
385- className = " grid w-full text-xs hover:bg-white/5 transition-colors"
391+ className = { ` grid w-full text-xs transition-colors cursor-pointer ${ selected ? "bg-accentbg" : " hover:bg-white/5" } ` }
386392 style = { { gridTemplateColumns : gridTemplate , height : RowHeight } }
393+ onClick = { ( ) => onSelect ( proc . pid ) }
387394 >
388- < div className = "px-2 py-[3px] truncate text-right text-secondary font-mono text-[11px]" > { proc . pid } </ div >
389- < div className = "px-2 py-[3px] truncate" > { proc . command } </ div >
390- { showStatus && < div className = "px-2 py-[3px] truncate text-secondary text-[11px]" > { proc . status } </ div > }
391- < div className = "px-2 py-[3px] truncate text-secondary" > { proc . user } </ div >
395+ < div className = "px-2 flex items-center truncate justify-end text-secondary font-mono text-[11px]" > { proc . pid } </ div >
396+ < div className = "px-2 flex items-center truncate" > { proc . command } </ div >
397+ { showStatus && < div className = "px-2 flex items-center truncate text-secondary text-[11px]" > { proc . status } </ div > }
398+ < div className = "px-2 flex items-center truncate text-secondary" > { proc . user } </ div >
392399 { showThreads && (
393- < div className = "px-2 py-[3px] truncate text-right text-secondary font-mono text-[11px]" >
400+ < div className = "px-2 flex items-center truncate justify-end text-secondary font-mono text-[11px]" >
394401 { proc . numthreads > 1 ? proc . numthreads : "" }
395402 </ div >
396403 ) }
397- < div className = "px-2 py-[3px] truncate text-right font-mono text-[11px]" >
404+ < div className = "px-2 flex items-center truncate justify-end font-mono text-[11px]" >
398405 { hasCpu && proc . cpu != null ? fmtCpu ( proc . cpu ) : "" }
399406 </ div >
400- < div className = "px-2 py-[3px] truncate text-right font-mono text-[11px]" > { fmtMem ( proc . mem ) } </ div >
407+ < div className = "px-2 flex items-center truncate justify-end font-mono text-[11px]" > { fmtMem ( proc . mem ) } </ div >
401408 </ div >
402409 ) ;
403410} ) ;
@@ -535,10 +542,18 @@ export const ProcessViewerView: React.FC<ViewComponentProps<ProcessViewerViewMod
535542 const loading = jotai . useAtomValue ( model . loadingAtom ) ;
536543 const error = jotai . useAtomValue ( model . errorAtom ) ;
537544 const scrollTop = jotai . useAtomValue ( model . scrollTopAtom ) ;
545+ const [ selectedPid , setSelectedPid ] = jotai . useAtom ( model . selectedPidAtom ) ;
538546 const bodyScrollRef = React . useRef < HTMLDivElement > ( null ) ;
539547 const containerRef = React . useRef < HTMLDivElement > ( null ) ;
540548 const [ wide , setWide ] = React . useState ( false ) ;
541549
550+ const handleSelectPid = React . useCallback (
551+ ( pid : number ) => {
552+ setSelectedPid ( ( cur ) => ( cur === pid ? null : pid ) ) ;
553+ } ,
554+ [ setSelectedPid ]
555+ ) ;
556+
542557 const platform = data ?. platform ?? "" ;
543558 const startIdx = Math . max ( 0 , Math . floor ( scrollTop / RowHeight ) - OverscanRows ) ;
544559 const totalCount = data ?. totalcount ?? 0 ;
@@ -591,7 +606,14 @@ export const ProcessViewerView: React.FC<ViewComponentProps<ProcessViewerViewMod
591606 < div style = { { height : totalHeight , position : "relative" } } >
592607 < div style = { { position : "absolute" , top : paddingTop , left : 0 , right : 0 } } >
593608 { processes . map ( ( proc ) => (
594- < ProcessRow key = { proc . pid } proc = { proc } hasCpu = { hasCpu } platform = { platform } />
609+ < ProcessRow
610+ key = { proc . pid }
611+ proc = { proc }
612+ hasCpu = { hasCpu }
613+ platform = { platform }
614+ selected = { selectedPid === proc . pid }
615+ onSelect = { handleSelectPid }
616+ />
595617 ) ) }
596618 </ div >
597619 </ div >
0 commit comments