@@ -28,14 +28,21 @@ import UtilityView from '../../UtilityView';
2828import ToolView , { getToolTabParams } from '../../ToolView' ;
2929import { ApplicationStateProvider , useApplicationState } from '../../../../settings/static/ApplicationStateProvider' ;
3030import { BROWSER_PANELS , WORKSPACES } from '../../../../browser/static/js/constants' ;
31+ import { getServerColors } from '../../utils' ;
32+ import pgWindow from 'sources/window' ;
3133
3234export function TabTitle ( { id, closable, defaultInternal} ) {
3335 const layoutDocker = React . useContext ( LayoutDockerContext ) ;
3436 const internal = layoutDocker ?. find ( id ) ?. internal ?? defaultInternal ;
37+ const showServerColorIndicator = usePreferences (
38+ ( state ) => state . getPreferencesForModule ( 'browser' ) ?. show_server_color_indicator ?? false
39+ ) ;
3540 const [ attrs , setAttrs ] = useState ( {
3641 icon : internal . icon ,
3742 title : internal . title ,
3843 tooltip : internal . tooltip ?? internal . title ,
44+ bgcolor : internal . bgcolor ,
45+ fgcolor : internal . fgcolor ,
3946 } ) ;
4047 const onContextMenu = useCallback ( ( e ) => {
4148 const g = layoutDocker . find ( id ) ?. group ?? '' ;
@@ -53,17 +60,62 @@ export function TabTitle({id, closable, defaultInternal}) {
5360 icon : internal . icon ,
5461 title : internal . title ,
5562 tooltip : internal . tooltip ?? internal . title ,
63+ bgcolor : internal . bgcolor ,
64+ fgcolor : internal . fgcolor ,
5665 } ) ;
5766 layoutDocker . saveLayout ( ) ;
5867 }
5968 } ) ;
6069
61- return ( ) => deregister ?. ( ) ;
70+ // Listen for server property updates to refresh colors
71+ // When a server's bgcolor/fgcolor is changed, this event is triggered
72+ // and we update the tab colors accordingly
73+ const serverUpdatedHandler = ( _item , newNodeData ) => {
74+ if ( newNodeData . _type === 'server' ) {
75+ const panelData = layoutDocker ?. find ( id ) ;
76+ if ( panelData ?. internal ) {
77+ const serverId = panelData . internal . server_id ;
78+ if ( serverId && serverId === newNodeData . _id ) {
79+ const { bgcolor, fgcolor } = getServerColors ( newNodeData . icon ) ;
80+ // Update internal data and attrs
81+ panelData . internal . bgcolor = bgcolor ;
82+ panelData . internal . fgcolor = fgcolor ;
83+ setAttrs ( prev => ( {
84+ ...prev ,
85+ bgcolor : bgcolor ,
86+ fgcolor : fgcolor ,
87+ } ) ) ;
88+ }
89+ }
90+ }
91+ } ;
92+
93+ pgWindow . pgAdmin ?. Browser ?. Events ?. on ( 'pgadmin:browser:node:updated' , serverUpdatedHandler ) ;
94+
95+ return ( ) => {
96+ deregister ?. ( ) ;
97+ pgWindow . pgAdmin ?. Browser ?. Events ?. off ( 'pgadmin:browser:node:updated' , serverUpdatedHandler ) ;
98+ } ;
6299 } , [ ] ) ;
63100
64101 return (
65102 < Box display = "flex" alignItems = "center" title = { attrs . tooltip } onContextMenu = { onContextMenu } width = "100%" >
66103 { attrs . icon && < span className = { `dock-tab-icon ${ attrs . icon } ` } > </ span > }
104+ { showServerColorIndicator && attrs . bgcolor && ! layoutDocker . isTabVisible ( id ) && (
105+ < Box
106+ component = "span"
107+ sx = { {
108+ width : '12px' ,
109+ height : '12px' ,
110+ borderRadius : '50%' ,
111+ backgroundColor : attrs . bgcolor ,
112+ marginLeft : '2px' ,
113+ marginRight : '4px' ,
114+ flexShrink : 0 ,
115+ border : '1px solid rgba(0, 0, 0, 0.1)' ,
116+ } }
117+ />
118+ ) }
67119 < span style = { { textOverflow : 'ellipsis' , overflow : 'hidden' , whiteSpace : 'nowrap' } } data-visible = { layoutDocker . isTabVisible ( id ) } > { attrs . title } </ span >
68120 { closable && < PgIconButton title = { gettext ( 'Close' ) } icon = { < CloseIcon style = { { height : '0.7em' } } /> } size = "xs" noBorder onClick = { ( ) => {
69121 layoutDocker . close ( id ) ;
@@ -368,14 +420,16 @@ export class LayoutDocker {
368420 this . saveLayout ( ) ;
369421 }
370422
371- static getPanel ( { icon, title, closable, tooltip, renamable, manualClose, ...attrs } ) {
423+ static getPanel ( { icon, title, closable, tooltip, renamable, manualClose, bgcolor , fgcolor , ...attrs } ) {
372424 const internal = {
373425 icon : icon ,
374426 title : title ,
375427 tooltip : tooltip ,
376428 closable : _ . isUndefined ( closable ) ? manualClose : closable ,
377429 renamable : renamable ,
378430 manualClose : manualClose ,
431+ bgcolor : bgcolor ,
432+ fgcolor : fgcolor ,
379433 } ;
380434 return {
381435 cached : true ,
0 commit comments