11import React from 'react' ;
22
3- import { CircleCheckFill , CircleXmarkFill } from '@gravity-ui/icons ' ;
4- import { DefinitionList , Flex , Icon , Label , Text } from '@gravity-ui/uikit' ;
3+ import { DefinitionList , Flex , Label , Text } from '@gravity-ui/uikit ' ;
4+ import type { LabelProps } from '@gravity-ui/uikit' ;
55
66import type { TBridgePile } from '../../../../types/api/cluster' ;
7+ import { BridgePileState } from '../../../../types/api/cluster' ;
78import { cn } from '../../../../utils/cn' ;
89import { EMPTY_DATA_PLACEHOLDER } from '../../../../utils/constants' ;
910import { formatNumber } from '../../../../utils/dataFormatters/dataFormatters' ;
@@ -13,6 +14,27 @@ import './BridgeInfoTable.scss';
1314
1415const b = cn ( 'bridge-info-table' ) ;
1516
17+ function getBridgePileStateTheme ( state ?: string ) : NonNullable < LabelProps [ 'theme' ] > {
18+ if ( ! state ) {
19+ return 'unknown' ;
20+ }
21+
22+ switch ( state . toUpperCase ( ) ) {
23+ case BridgePileState . PRIMARY :
24+ case BridgePileState . PROMOTE :
25+ case BridgePileState . SYNCHRONIZED :
26+ return 'success' ; // Green - healthy states
27+ case BridgePileState . NOT_SYNCHRONIZED :
28+ return 'warning' ; // Yellow - needs attention
29+ case BridgePileState . SUSPENDED :
30+ case BridgePileState . DISCONNECTED :
31+ return 'danger' ; // Red - critical states
32+ case BridgePileState . UNSPECIFIED :
33+ default :
34+ return 'unknown' ; // Purple - unknown state
35+ }
36+ }
37+
1638interface BridgeInfoTableProps {
1739 piles : TBridgePile [ ] ;
1840}
@@ -22,57 +44,17 @@ interface BridgePileCardProps {
2244}
2345
2446const BridgePileCard = React . memo ( function BridgePileCard ( { pile} : BridgePileCardProps ) {
25- const renderPrimaryStatus = React . useCallback ( ( ) => {
26- const isPrimary = pile . IsPrimary ;
27- const icon = isPrimary ? CircleCheckFill : CircleXmarkFill ;
28- const text = isPrimary ? i18n ( 'value_yes' ) : i18n ( 'value_no' ) ;
29-
30- return (
31- < Flex gap = { 1 } alignItems = "center" >
32- < Icon data = { icon } size = { 16 } className = { b ( 'status-icon' , { primary : isPrimary } ) } />
33- < Text color = "secondary" > { text } </ Text >
34- </ Flex >
35- ) ;
36- } , [ pile . IsPrimary ] ) ;
37-
3847 const renderStateStatus = React . useCallback ( ( ) => {
3948 if ( ! pile . State ) {
4049 return EMPTY_DATA_PLACEHOLDER ;
4150 }
4251
43- const isSynchronized = pile . State . toUpperCase ( ) === 'SYNCHRONIZED' ;
44- const theme = isSynchronized ? 'success' : 'info' ;
45-
52+ const theme = getBridgePileStateTheme ( pile . State ) ;
4653 return < Label theme = { theme } > { pile . State } </ Label > ;
4754 } , [ pile . State ] ) ;
4855
49- const renderBeingPromotedStatus = React . useCallback ( ( ) => {
50- const isBeingPromoted = pile . IsBeingPromoted ;
51- const icon = isBeingPromoted ? CircleCheckFill : CircleXmarkFill ;
52- const text = isBeingPromoted ? i18n ( 'value_yes' ) : i18n ( 'value_no' ) ;
53-
54- return (
55- < Flex gap = { 1 } alignItems = "center" >
56- < Icon
57- data = { icon }
58- size = { 16 }
59- className = { b ( 'status-icon' , { primary : isBeingPromoted } ) }
60- />
61- < Text color = "secondary" > { text } </ Text >
62- </ Flex >
63- ) ;
64- } , [ pile . IsBeingPromoted ] ) ;
65-
6656 const info = React . useMemo (
6757 ( ) => [
68- {
69- name : i18n ( 'field_primary' ) ,
70- content : renderPrimaryStatus ( ) ,
71- } ,
72- {
73- name : i18n ( 'field_being-promoted' ) ,
74- content : renderBeingPromotedStatus ( ) ,
75- } ,
7658 {
7759 name : i18n ( 'field_state' ) ,
7860 content : renderStateStatus ( ) ,
@@ -83,7 +65,7 @@ const BridgePileCard = React.memo(function BridgePileCard({pile}: BridgePileCard
8365 pile . Nodes === undefined ? EMPTY_DATA_PLACEHOLDER : formatNumber ( pile . Nodes ) ,
8466 } ,
8567 ] ,
86- [ renderPrimaryStatus , renderBeingPromotedStatus , renderStateStatus , pile . Nodes ] ,
68+ [ renderStateStatus , pile . Nodes ] ,
8769 ) ;
8870
8971 return (
0 commit comments