@@ -185,6 +185,7 @@ export function SidebarControls({
185185 const activeFacets : IssueLikeFacets = prMode ? prFacets : issueFacets ;
186186 const orgSelection = ticketMode ? activeFilters . orgs : repoFilters . orgs ;
187187 const orgEntries = ticketMode ? activeFacets . orgs : repoFacets . orgs ;
188+ const activeAuthorSelection = activeFilters . authorMode === "include" ? activeFilters . authors : activeFilters . excludedAuthors ;
188189 const onActiveFiltersChange = ( next : IssueFilters | PullRequestFilters ) => {
189190 if ( prMode ) onPrFiltersChange ( next as PullRequestFilters ) ;
190191 else onIssueFiltersChange ( next as IssueFilters ) ;
@@ -273,8 +274,40 @@ export function SidebarControls({
273274 < FilterSection title = { t ( "sidebar.labels" ) } activeCount = { activeFilters . labels . size } dataFor = { prMode ? "prs-only" : "issues-only" } onClear = { ( ) => onActiveFiltersChange ( { ...activeFilters , labels : new Set ( ) } ) } >
274275 < CheckList entries = { [ ...activeFacets . labels . entries ( ) ] } selected = { activeFilters . labels } showSwatch onToggle = { ( value ) => onActiveFiltersChange ( { ...activeFilters , labels : toggleSetValue ( activeFilters . labels , value ) } ) } />
275276 </ FilterSection >
276- < FilterSection title = { t ( "sidebar.authors" ) } activeCount = { activeFilters . authors . size } dataFor = { prMode ? "prs-only" : "issues-only" } onClear = { ( ) => onActiveFiltersChange ( { ...activeFilters , authors : new Set ( ) } ) } >
277- < CheckList entries = { [ ...activeFacets . authors . entries ( ) ] } selected = { activeFilters . authors } onToggle = { ( value ) => onActiveFiltersChange ( { ...activeFilters , authors : toggleSetValue ( activeFilters . authors , value ) } ) } />
277+ < FilterSection
278+ title = { t ( "sidebar.authors" ) }
279+ activeCount = { activeFilters . authors . size + activeFilters . excludedAuthors . size }
280+ dataFor = { prMode ? "prs-only" : "issues-only" }
281+ onClear = { ( ) => onActiveFiltersChange ( { ...activeFilters , authors : new Set ( ) , excludedAuthors : new Set ( ) } ) }
282+ >
283+ < div className = "opt-group author-mode" role = "group" aria-label = { t ( "sidebar.authorFilterMode" ) } >
284+ { ( [ "include" , "exclude" ] as const ) . map ( ( mode ) => (
285+ < button
286+ type = "button"
287+ key = { mode }
288+ className = { activeFilters . authorMode === mode ? "active" : "" }
289+ onClick = { ( ) => onActiveFiltersChange ( { ...activeFilters , authorMode : mode } ) }
290+ >
291+ { t ( mode === "include" ? "sidebar.includeAuthors" : "sidebar.excludeAuthors" ) }
292+ </ button >
293+ ) ) }
294+ </ div >
295+ < CheckList
296+ entries = { [ ...activeFacets . authors . entries ( ) ] }
297+ selected = { activeAuthorSelection }
298+ onToggle = { ( value ) => {
299+ const authors = new Set ( activeFilters . authors ) ;
300+ const excludedAuthors = new Set ( activeFilters . excludedAuthors ) ;
301+ const target = activeFilters . authorMode === "include" ? authors : excludedAuthors ;
302+ const opposite = activeFilters . authorMode === "include" ? excludedAuthors : authors ;
303+ if ( target . has ( value ) ) target . delete ( value ) ;
304+ else {
305+ target . add ( value ) ;
306+ opposite . delete ( value ) ;
307+ }
308+ onActiveFiltersChange ( { ...activeFilters , authors, excludedAuthors } ) ;
309+ } }
310+ />
278311 </ FilterSection >
279312 < FilterSection title = { t ( "sidebar.assignees" ) } activeCount = { activeFilters . assignees . size } dataFor = { prMode ? "prs-only" : "issues-only" } onClear = { ( ) => onActiveFiltersChange ( { ...activeFilters , assignees : new Set ( ) } ) } >
280313 < CheckList entries = { [ ...activeFacets . assignees . entries ( ) ] } selected = { activeFilters . assignees } onToggle = { ( value ) => onActiveFiltersChange ( { ...activeFilters , assignees : toggleSetValue ( activeFilters . assignees , value ) } ) } />
0 commit comments