@@ -65,6 +65,7 @@ import { mapToSupportedLanguage } from "./i18n/languageUtils";
6565interface PackageEntry {
6666 name : string ;
6767 installedVersion : string ;
68+ installReason ?: "on_request" | "dependency" | "unknown" ;
6869 latestVersion ?: string ;
6970 size ?: string ;
7071 desc ?: string ;
@@ -133,6 +134,7 @@ const WailBrewApp = () => {
133134 const [ deprecatedFormulae , setDeprecatedFormulae ] = useState < string [ ] > ( [ ] ) ;
134135 const [ selectedDeprecatedPackage , setSelectedDeprecatedPackage ] = useState < PackageEntry | null > ( null ) ;
135136 const [ updatableError , setUpdatableError ] = useState < string > ( "" ) ;
137+ const [ installedFilter , setInstalledFilter ] = useState < "all" | "on_request" | "dependency" > ( "all" ) ;
136138 const [ homebrewLog , setHomebrewLog ] = useState < string > ( "" ) ;
137139 const [ homebrewVersion , setHomebrewVersion ] = useState < string > ( "" ) ;
138140 const [ homebrewUpdateStatus , setHomebrewUpdateStatus ] = useState < { isUpToDate : boolean | null , latestVersion : string | null } > ( { isUpToDate : null , latestVersion : null } ) ;
@@ -237,10 +239,11 @@ const WailBrewApp = () => {
237239 throw new Error ( `${ t ( 'errors.failedRepositories' ) } : ${ safeRepos [ 0 ] [ 1 ] } ` ) ;
238240 }
239241
240- const installedFormatted = safeInstalled . map ( ( [ name , installedVersion , size ] ) => ( {
242+ const installedFormatted = safeInstalled . map ( ( [ name , installedVersion , size , installReason ] ) => ( {
241243 name,
242244 installedVersion,
243245 size,
246+ installReason : ( installReason as "on_request" | "dependency" | "unknown" ) || "unknown" ,
244247 isInstalled : true ,
245248 } ) ) ;
246249 const casksFormatted = safeInstalledCasks . map ( ( [ name , installedVersion , size ] ) => ( {
@@ -1084,13 +1087,22 @@ const WailBrewApp = () => {
10841087 const activePackages = getActivePackages ( ) ;
10851088 const activeRepositories = getActiveRepositories ( ) ;
10861089
1087- const filteredPackages = activePackages . filter ( ( pkg ) =>
1090+ const installedFilteredPackages = view === "installed"
1091+ ? activePackages . filter ( ( pkg ) => {
1092+ if ( installedFilter === "all" ) return true ;
1093+ return pkg . installReason === installedFilter ;
1094+ } )
1095+ : activePackages ;
1096+
1097+ const filteredPackages = installedFilteredPackages . filter ( ( pkg ) =>
10881098 pkg . name . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) )
10891099 ) ;
10901100
10911101 const filteredRepositories = activeRepositories . filter ( ( repo ) =>
10921102 repo . name . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) )
10931103 ) ;
1104+ const installedOnRequestCount = packages . filter ( pkg => pkg . installReason === "on_request" ) . length ;
1105+ const installedDependencyCount = packages . filter ( pkg => pkg . installReason === "dependency" ) . length ;
10941106
10951107 const handleSelect = async ( pkg : PackageEntry ) => {
10961108 setSelectedPackage ( pkg ) ;
@@ -2006,10 +2018,11 @@ const WailBrewApp = () => {
20062018 setError ( safeInstalled [ 0 ] [ 1 ] ) ;
20072019 setPackages ( [ ] ) ;
20082020 } else {
2009- const formatted = safeInstalled . map ( ( [ name , installedVersion , size ] ) => ( {
2021+ const formatted = safeInstalled . map ( ( [ name , installedVersion , size , installReason ] ) => ( {
20102022 name,
20112023 installedVersion,
20122024 size,
2025+ installReason : ( installReason as "on_request" | "dependency" | "unknown" ) || "unknown" ,
20132026 isInstalled : true ,
20142027 } ) ) ;
20152028 setPackages ( formatted ) ;
@@ -2178,19 +2191,37 @@ const WailBrewApp = () => {
21782191 < HeaderRow
21792192 title = { t ( 'headers.installedFormulas' , { count : packages . length } ) }
21802193 actions = {
2181- < button
2182- className = "refresh-button"
2183- onClick = { handleRefreshPackages }
2184- disabled = { loading }
2185- title = { t ( 'buttons.refresh' ) }
2186- >
2187- < RefreshCw size = { 18 } />
2188- </ button >
2194+ < >
2195+ < button
2196+ className = "refresh-button"
2197+ onClick = { handleRefreshPackages }
2198+ disabled = { loading }
2199+ title = { t ( 'buttons.refresh' ) }
2200+ >
2201+ < RefreshCw size = { 18 } />
2202+ </ button >
2203+ </ >
21892204 }
21902205 searchQuery = { searchQuery }
21912206 onSearchChange = { setSearchQuery }
21922207 onClearSearch = { ( ) => setSearchQuery ( "" ) }
21932208 />
2209+ < div className = "installed-filter-pills-row" >
2210+ < button
2211+ className = { `installed-filter-pill ${ installedFilter === "on_request" ? "active" : "" } ` }
2212+ onClick = { ( ) => setInstalledFilter ( prev => prev === "on_request" ? "all" : "on_request" ) }
2213+ title = { t ( 'filters.toggleOnRequest' ) }
2214+ >
2215+ { t ( 'filters.onRequest' , { count : installedOnRequestCount } ) }
2216+ </ button >
2217+ < button
2218+ className = { `installed-filter-pill ${ installedFilter === "dependency" ? "active" : "" } ` }
2219+ onClick = { ( ) => setInstalledFilter ( prev => prev === "dependency" ? "all" : "dependency" ) }
2220+ title = { t ( 'filters.toggleAsDependency' ) }
2221+ >
2222+ { t ( 'filters.asDependency' , { count : installedDependencyCount } ) }
2223+ </ button >
2224+ </ div >
21942225 { error && < div className = "result error" > { error } </ div > }
21952226 < PackageTable
21962227 ref = { view === "installed" ? packageTableRef : null }
@@ -2235,7 +2266,7 @@ const WailBrewApp = () => {
22352266 onSearchChange = { setSearchQuery }
22362267 onClearSearch = { ( ) => setSearchQuery ( "" ) }
22372268 />
2238- { updatableError && < div className = "result error" > { updatableError } </ div > }
2269+ { error && < div className = "result error" > { error } </ div > }
22392270 < PackageTable
22402271 ref = { view === "casks" ? packageTableRef : null }
22412272 packages = { filteredPackages }
0 commit comments