@@ -10,6 +10,7 @@ import {
1010import { fetchOrgs , fetchRepos , discoverUpstreamRepos , OrgEntry , RepoRef , RepoEntry } from "../../services/api" ;
1111import { getClient } from "../../services/github" ;
1212import { user } from "../../stores/auth" ;
13+ import type { TrackedUser } from "../../stores/config" ;
1314import { relativeTime } from "../../lib/format" ;
1415import LoadingSpinner from "../shared/LoadingSpinner" ;
1516import FilterInput from "../shared/FilterInput" ;
@@ -25,7 +26,9 @@ interface RepoSelectorProps {
2526 showUpstreamDiscovery ?: boolean ;
2627 upstreamRepos ?: RepoRef [ ] ;
2728 onUpstreamChange ?: ( repos : RepoRef [ ] ) => void ;
28- trackedUsers ?: { login : string ; avatarUrl : string ; name : string | null } [ ] ;
29+ trackedUsers ?: TrackedUser [ ] ;
30+ monitoredRepos ?: RepoRef [ ] ;
31+ onMonitorToggle ?: ( repo : RepoRef , monitored : boolean ) => void ;
2932}
3033
3134interface OrgRepoState {
@@ -225,6 +228,10 @@ export default function RepoSelector(props: RepoSelectorProps) {
225228 new Set ( props . selected . map ( ( r ) => r . fullName ) )
226229 ) ;
227230
231+ const monitoredSet = createMemo ( ( ) =>
232+ new Set ( ( props . monitoredRepos ?? [ ] ) . map ( ( r ) => r . fullName ) )
233+ ) ;
234+
228235 const sortedOrgStates = createMemo ( ( ) => {
229236 const states = orgStates ( ) ;
230237 // Defer sorting until all orgs have loaded: prevents layout shift during
@@ -527,26 +534,48 @@ export default function RepoSelector(props: RepoSelectorProps) {
527534 { ( repo ) => {
528535 return (
529536 < li >
530- < label class = "flex cursor-pointer items-start gap-3 px-4 py-3 hover:bg-base-200" >
531- < input
532- type = "checkbox"
533- checked = { isSelected ( repo ( ) . fullName ) }
534- onChange = { ( ) => toggleRepo ( repo ( ) ) }
535- class = "checkbox checkbox-primary checkbox-sm mt-0.5"
536- />
537- < div class = "min-w-0 flex-1" >
538- < div class = "flex items-center gap-2" >
539- < span class = "min-w-0 truncate text-sm font-medium text-base-content" >
540- { repo ( ) . name }
541- </ span >
542- < Show when = { repo ( ) . pushedAt } >
543- < span class = "ml-auto shrink-0 text-xs text-base-content/60" >
544- { relativeTime ( repo ( ) . pushedAt ! ) }
537+ < div class = "flex items-center" >
538+ < label class = "flex cursor-pointer items-start gap-3 px-4 py-3 hover:bg-base-200 flex-1" >
539+ < input
540+ type = "checkbox"
541+ checked = { isSelected ( repo ( ) . fullName ) }
542+ onChange = { ( ) => toggleRepo ( repo ( ) ) }
543+ class = "checkbox checkbox-primary checkbox-sm mt-0.5"
544+ />
545+ < div class = "min-w-0 flex-1" >
546+ < div class = "flex items-center gap-2" >
547+ < span class = "min-w-0 truncate text-sm font-medium text-base-content" >
548+ { repo ( ) . name }
545549 </ span >
546- </ Show >
550+ < Show when = { repo ( ) . pushedAt } >
551+ < span class = "ml-auto shrink-0 text-xs text-base-content/60" >
552+ { relativeTime ( repo ( ) . pushedAt ! ) }
553+ </ span >
554+ </ Show >
555+ </ div >
547556 </ div >
548- </ div >
549- </ label >
557+ </ label >
558+ < Show when = { isSelected ( repo ( ) . fullName ) && props . onMonitorToggle && ! upstreamSelectedSet ( ) . has ( repo ( ) . fullName ) } >
559+ < button
560+ type = "button"
561+ onClick = { ( e ) => {
562+ e . stopPropagation ( ) ;
563+ props . onMonitorToggle ?.( toRepoRef ( repo ( ) ) , ! monitoredSet ( ) . has ( repo ( ) . fullName ) ) ;
564+ } }
565+ class = "btn btn-ghost btn-sm btn-circle mr-2"
566+ classList = { { "opacity-40" : ! monitoredSet ( ) . has ( repo ( ) . fullName ) } }
567+ title = { monitoredSet ( ) . has ( repo ( ) . fullName ) ? "Stop monitoring all activity" : "Monitor all activity" }
568+ aria-label = { monitoredSet ( ) . has ( repo ( ) . fullName ) ? "Stop monitoring all activity" : "Monitor all activity" }
569+ aria-pressed = { monitoredSet ( ) . has ( repo ( ) . fullName ) }
570+ >
571+ { /* Heroicons eye outline 16px */ }
572+ < svg xmlns = "http://www.w3.org/2000/svg" class = "h-4 w-4" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" stroke-width = { 2 } aria-hidden = "true" >
573+ < path stroke-linecap = "round" stroke-linejoin = "round" d = "M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
574+ < path stroke-linecap = "round" stroke-linejoin = "round" d = "M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
575+ </ svg >
576+ </ button >
577+ </ Show >
578+ </ div >
550579 </ li >
551580 ) ;
552581 } }
0 commit comments