@@ -26,13 +26,16 @@ import {
2626 Tooltip ,
2727 Alert ,
2828 CircularProgress ,
29+ Collapse ,
2930} from '@mui/material' ;
3031import DarkModeIcon from '@mui/icons-material/DarkMode' ;
3132import LanguageIcon from '@mui/icons-material/Language' ;
3233import StorageIcon from '@mui/icons-material/Storage' ;
3334import AddIcon from '@mui/icons-material/Add' ;
3435import CloseIcon from '@mui/icons-material/Close' ;
3536import SettingsIcon from '@mui/icons-material/Settings' ;
37+ import ExpandMoreIcon from '@mui/icons-material/ExpandMore' ;
38+ import ExpandLessIcon from '@mui/icons-material/ExpandLess' ;
3639import { useTheme } from '../contexts/ServiceContext' ;
3740import { getAllModules , getModuleById } from '../plugins' ;
3841import { DynamicModuleConfig } from '../types/index' ;
@@ -83,6 +86,12 @@ const Settings = () => {
8386 const [ isLoading , setIsLoading ] = useState < boolean > ( true ) ;
8487 const [ error , setError ] = useState < string | null > ( null ) ;
8588
89+ // Collapsed state per plugin panel
90+ const [ collapsed , setCollapsed ] = useState < Record < string , boolean > > ( { } ) ;
91+ const pluginKey = ( p : SettingsPlugin ) => `${ p . pluginId } -${ p . moduleId } ` ;
92+ const toggleCollapsed = ( key : string ) =>
93+ setCollapsed ( ( prev ) => ( { ...prev , [ key ] : ! prev [ key ] } ) ) ;
94+
8695 // Handle theme change
8796 const handleThemeChange = ( ) => {
8897 const newTheme =
@@ -382,6 +391,34 @@ const Settings = () => {
382391 ) ;
383392 } , [ activePlugins , selectedCategory ] ) ;
384393
394+ // Count of active plugins per category for display in Category dropdown
395+ const activeCountByCategory = useMemo ( ( ) => {
396+ const m : Record < string , number > = { } ;
397+ activePlugins . forEach ( ( p ) => {
398+ m [ p . category ] = ( m [ p . category ] || 0 ) + 1 ;
399+ } ) ;
400+ return m ;
401+ } , [ activePlugins ] ) ;
402+
403+ // Ensure default collapsed state: new plugin panels start collapsed
404+ useEffect ( ( ) => {
405+ setCollapsed ( ( prev ) => {
406+ const next : Record < string , boolean > = { ...prev } ;
407+ // Add defaults for new active plugins
408+ activePlugins . forEach ( ( p ) => {
409+ const key = pluginKey ( p ) ;
410+ if ( next [ key ] === undefined ) next [ key ] = true ; // collapsed by default
411+ } ) ;
412+ // Clean up keys for plugins no longer active
413+ Object . keys ( next ) . forEach ( ( k ) => {
414+ if ( ! activePlugins . some ( ( p ) => pluginKey ( p ) === k ) ) {
415+ delete next [ k ] ;
416+ }
417+ } ) ;
418+ return next ;
419+ } ) ;
420+ } , [ activePlugins ] ) ;
421+
385422 // Add a plugin to the active list
386423 const handleAddPlugin = ( ) => {
387424 if ( ! selectedPlugin ) return ;
@@ -446,12 +483,15 @@ const Settings = () => {
446483 id = "category-select"
447484 value = { selectedCategory }
448485 label = "Category"
486+ renderValue = { ( value ) =>
487+ `${ value as string } (${ activeCountByCategory [ value as string ] || 0 } )`
488+ }
449489 onChange = { ( e ) => setSelectedCategory ( e . target . value ) }
450490 disabled = { isLoading || categories . length === 0 }
451491 >
452492 { categories . map ( ( category ) => (
453493 < MenuItem key = { category } value = { category } >
454- { category }
494+ { category } ( { activeCountByCategory [ category ] || 0 } )
455495 </ MenuItem >
456496 ) ) }
457497 </ Select >
@@ -522,33 +562,51 @@ const Settings = () => {
522562 title = { plugin . displayName }
523563 subheader = { `Priority: ${ plugin . priority } ` }
524564 action = {
525- < Tooltip title = "Remove" >
526- < IconButton
527- aria-label = "remove"
528- onClick = { ( ) => handleRemovePlugin ( plugin ) }
529- size = "small"
530- >
531- < CloseIcon />
532- </ IconButton >
533- </ Tooltip >
565+ < >
566+ < Tooltip title = { collapsed [ pluginKey ( plugin ) ] ? 'Expand' : 'Collapse' } >
567+ < IconButton
568+ aria-label = "toggle"
569+ aria-expanded = { ! collapsed [ pluginKey ( plugin ) ] }
570+ onClick = { ( ) => toggleCollapsed ( pluginKey ( plugin ) ) }
571+ size = "small"
572+ >
573+ { collapsed [ pluginKey ( plugin ) ] ? (
574+ < ExpandMoreIcon />
575+ ) : (
576+ < ExpandLessIcon />
577+ ) }
578+ </ IconButton >
579+ </ Tooltip >
580+ < Tooltip title = "Remove" >
581+ < IconButton
582+ aria-label = "remove"
583+ onClick = { ( ) => handleRemovePlugin ( plugin ) }
584+ size = "small"
585+ >
586+ < CloseIcon />
587+ </ IconButton >
588+ </ Tooltip >
589+ </ >
534590 }
535591 avatar = { < SettingsIcon /> }
536592 />
537- < CardContent sx = { { flexGrow : 1 , overflow : 'auto' , minHeight : '200px' } } >
538- < LegacyModuleAdapter
539- pluginId = { plugin . pluginId }
540- moduleId = { plugin . moduleId }
541- moduleName = { plugin . moduleName }
542- isLocal = { false }
543- useUnifiedRenderer = { true }
544- mode = "published"
545- lazyLoading = { true }
546- priority = "normal"
547- enableMigrationWarnings = { process . env . NODE_ENV === 'development' }
548- fallbackStrategy = "on-error"
549- performanceMonitoring = { process . env . NODE_ENV === 'development' }
550- />
551- </ CardContent >
593+ < Collapse in = { ! collapsed [ pluginKey ( plugin ) ] } timeout = "auto" unmountOnExit >
594+ < CardContent sx = { { flexGrow : 1 , overflow : 'auto' , minHeight : '200px' } } >
595+ < LegacyModuleAdapter
596+ pluginId = { plugin . pluginId }
597+ moduleId = { plugin . moduleId }
598+ moduleName = { plugin . moduleName }
599+ isLocal = { false }
600+ useUnifiedRenderer = { true }
601+ mode = "published"
602+ lazyLoading = { true }
603+ priority = "normal"
604+ enableMigrationWarnings = { process . env . NODE_ENV === 'development' }
605+ fallbackStrategy = "on-error"
606+ performanceMonitoring = { process . env . NODE_ENV === 'development' }
607+ />
608+ </ CardContent >
609+ </ Collapse >
552610 </ Card >
553611 </ Grid >
554612 ) )
0 commit comments