@@ -77,12 +77,7 @@ const SettingsMenu = () => {
7777 route : route . settings . privacy ,
7878 hasSubMenu : false ,
7979 isEnabled : true ,
80- } ,
81- {
82- title : 'common:modelProviders' ,
83- route : route . settings . model_providers ,
84- hasSubMenu : activeProviders . length > 0 ,
85- isEnabled : true ,
80+ dividerAfter : true ,
8681 } ,
8782 {
8883 title : 'common:assistants' ,
@@ -136,7 +131,7 @@ const SettingsMenu = () => {
136131 return (
137132 < >
138133 < div
139- className = 'h-full w-54 shrink-0 px-1.5 flex'
134+ className = 'h-full w-54 shrink-0 px-1.5 flex overflow-auto '
140135 >
141136 < div className = "flex flex-col gap-1 w-full font-medium" >
142137 { menuSettings . map ( ( menu ) => {
@@ -172,6 +167,8 @@ const SettingsMenu = () => {
172167 </ div >
173168 </ Link >
174169
170+ { menu . dividerAfter && < div className = "my-4" /> }
171+
175172 { /* Sub-menu for model providers */ }
176173 { menu . hasSubMenu && expandedProviders && (
177174 < div className = "ml-2 mt-1 space-y-1" >
@@ -222,8 +219,9 @@ const SettingsMenu = () => {
222219 </ div >
223220 )
224221 } ) }
222+
225223 { /* Integrations section */ }
226- < div className = "mt-3 " >
224+ < div className = "mt-4 " >
227225 < span className = "px-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground" >
228226 { t ( 'common:integrations' ) }
229227 </ span >
@@ -242,6 +240,74 @@ const SettingsMenu = () => {
242240 </ Link >
243241 </ div >
244242 </ div >
243+
244+ { /* Model Providers section */ }
245+ < div className = "mt-4" >
246+ < span className = "px-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground" >
247+ { t ( 'common:modelProviders' ) }
248+ </ span >
249+ < div className = "mt-1 flex flex-col gap-1" >
250+ < Link
251+ to = { route . settings . model_providers }
252+ className = "flex items-center justify-between px-2 py-1 cursor-pointer hover:dark:bg-secondary/60 hover:bg-secondary rounded-sm [&.active]:dark:bg-secondary/80 [&.active]:bg-secondary"
253+ >
254+ < span > { t ( 'common:modelProviders' ) } </ span >
255+ { activeProviders . length > 0 && (
256+ < button
257+ onClick = { ( e ) => {
258+ e . preventDefault ( )
259+ e . stopPropagation ( )
260+ toggleProvidersExpansion ( )
261+ } }
262+ className = "text-muted-foreground/60 hover:text-muted-foreground/80"
263+ >
264+ { expandedProviders ? (
265+ < IconChevronDown size = { 16 } />
266+ ) : (
267+ < IconChevronRight size = { 16 } />
268+ ) }
269+ </ button >
270+ ) }
271+ </ Link >
272+ { expandedProviders && activeProviders . map ( ( provider ) => {
273+ const isActive = matches . some (
274+ ( match ) =>
275+ match . routeId === '/settings/providers/$providerName' &&
276+ 'providerName' in match . params &&
277+ match . params . providerName === provider . provider
278+ )
279+ return (
280+ < div
281+ key = { provider . provider }
282+ className = { cn (
283+ 'flex px-2 items-center gap-1.5 cursor-pointer hover:bg-secondary/60 py-1 w-full rounded-sm text-foreground' ,
284+ isActive && 'bg-secondary' ,
285+ provider . provider === 'llama.cpp' &&
286+ stepSetupRemoteProvider &&
287+ 'hidden'
288+ ) }
289+ onClick = { ( ) =>
290+ navigate ( {
291+ to : route . settings . providers ,
292+ params : { providerName : provider . provider } ,
293+ ...( stepSetupRemoteProvider
294+ ? { search : { step : 'setup_remote_provider' } }
295+ : { } ) ,
296+ } )
297+ }
298+ >
299+ < ProvidersAvatar provider = { provider } />
300+ < div className = "truncate" >
301+ < span > { getProviderTitle ( provider . provider ) } </ span >
302+ </ div >
303+ </ div >
304+ )
305+ } ) }
306+ < div className = "m-2" />
307+ </ div >
308+ </ div >
309+
310+
245311 </ div >
246312 </ div >
247313 </ >
0 commit comments