1313 * See the License for the specific language governing permissions and
1414 * limitations under the License.
1515 */
16- import { ChartDonut , ChartThemeColor } from '@patternfly/react-charts/victory' ;
17- import WarningAmberIcon from '@mui/icons-material/WarningAmber ' ;
16+
17+ import { ChartDonut } from '@patternfly/react-charts/victory ' ;
1818import Card from '@mui/material/Card' ;
1919import CardContent from '@mui/material/CardContent' ;
2020import Typography from '@mui/material/Typography' ;
2121import Box from '@mui/material/Box' ;
2222import Divider from '@mui/material/Divider' ;
23+ import CircularProgress from '@mui/material/CircularProgress' ;
2324
24- export const Scorecard = ( ) => {
25- const openPRs = 22 ;
26-
27- // Determine status
28- let statusColor = ChartThemeColor . gray ;
29-
30- if ( openPRs >= 10 && openPRs <= 50 ) {
31- statusColor = '#F0AB00' ;
32- } else if ( openPRs > 50 ) {
33- statusColor = '#C9190B' ;
34- }
25+ interface ScorecardProps {
26+ cardTitle : string ;
27+ description : string ;
28+ loading : boolean ;
29+ statusColor : string ;
30+ StatusIcon : React . ElementType ;
31+ value : number ;
32+ thresholds : { key : string ; expression : string } [ ] ;
33+ }
3534
35+ const Scorecard = ( {
36+ cardTitle,
37+ description,
38+ loading,
39+ statusColor,
40+ StatusIcon,
41+ value,
42+ thresholds,
43+ } : ScorecardProps ) => {
3644 return (
3745 < Card
3846 style = { {
3947 width : '364px' ,
4048 borderRadius : 8 ,
41- border : '2px solid #ffffff1f' , // #0000001f
49+ border : '2px solid #0000001f' ,
4250 boxShadow : 'none' ,
4351 } }
4452 >
4553 < CardContent style = { { padding : 0 } } >
4654 < Box sx = { { p : 2 } } >
4755 < Typography variant = "h6" style = { { fontWeight : 500 } } >
48- Github open PRs
56+ { cardTitle }
4957 </ Typography >
5058 </ Box >
5159 < Divider />
5260 < Box sx = { { p : 2 } } >
5361 < Typography variant = "body2" color = "textSecondary" >
54- Current count of open Pull Requests for a given GitHub repository.
62+ { description }
5563 </ Typography >
5664 </ Box >
5765
@@ -62,77 +70,77 @@ export const Scorecard = () => {
6270 sx = { { p : 2 } }
6371 >
6472 < Box position = "relative" width = { 200 } height = { 200 } >
65- { /* ChartDonut */ }
66- < ChartDonut
67- ariaDesc = "Open PRs donut chart"
68- ariaTitle = "Open PRs"
69- constrainToVisibleArea
70- data = { [ { x : 'Open PRs' , y : openPRs } ] }
71- height = { 200 }
72- width = { 200 }
73- colorScale = { [ statusColor ] }
74- />
75-
76- { /* Overlay Content */ }
77- < Box
78- position = "absolute"
79- top = "50%"
80- left = "50%"
81- sx = { {
82- transform : 'translate(-50%, -50%)' ,
83- display : 'flex' ,
84- flexDirection : 'column' ,
85- alignItems : 'center' ,
86- } }
87- >
88- < WarningAmberIcon sx = { { color : statusColor , fontSize : 28 } } />
89- < Typography
90- variant = "h6"
91- style = { { color : statusColor , fontWeight : 600 } }
73+ { loading ? (
74+ < Box
75+ sx = { {
76+ position : 'absolute' ,
77+ top : '50%' ,
78+ left : '50%' ,
79+ transform : 'translate(-50%, -50%)' ,
80+ } }
9281 >
93- { openPRs }
94- </ Typography >
95- </ Box >
82+ < CircularProgress />
83+ </ Box >
84+ ) : (
85+ < >
86+ < ChartDonut
87+ constrainToVisibleArea
88+ data = { [ { x : cardTitle , y : value === 0 ? 1 : value } ] }
89+ height = { 200 }
90+ width = { 200 }
91+ colorScale = { [ statusColor ] }
92+ />
93+ < Box
94+ position = "absolute"
95+ top = "50%"
96+ left = "50%"
97+ sx = { {
98+ transform : 'translate(-50%, -50%)' ,
99+ display : 'flex' ,
100+ flexDirection : 'column' ,
101+ alignItems : 'center' ,
102+ } }
103+ >
104+ < StatusIcon sx = { { color : statusColor , fontSize : 24 } } />
105+ < Typography
106+ variant = "h6"
107+ style = { { color : statusColor , fontWeight : 600 } }
108+ >
109+ { value }
110+ </ Typography >
111+ </ Box >
112+ </ >
113+ ) }
96114 </ Box >
97115
98116 < Box sx = { { p : 0 } } >
99- < div
100- style = { { display : 'flex' , alignItems : 'center' , marginBottom : 8 } }
101- >
102- < div
103- style = { {
104- width : 10 ,
105- height : 10 ,
106- backgroundColor : '#3E8635' ,
107- marginRight : 8 ,
108- } }
109- />
110- < Typography variant = "body2" > Ideal < 10</ Typography >
111- </ div >
112- < div
113- style = { { display : 'flex' , alignItems : 'center' , marginBottom : 8 } }
114- >
115- < div
116- style = { {
117- width : 10 ,
118- height : 10 ,
119- backgroundColor : '#F0AB00' ,
120- marginRight : 8 ,
121- } }
122- />
123- < Typography variant = "body2" > Warning 10-50</ Typography >
124- </ div >
125- < div style = { { display : 'flex' , alignItems : 'center' } } >
117+ { thresholds . map ( ( { key, expression } ) => (
126118 < div
119+ key = { key }
127120 style = { {
128- width : 10 ,
129- height : 10 ,
130- backgroundColor : '#C9190B' ,
131- marginRight : 8 ,
121+ display : 'flex' ,
122+ alignItems : 'center' ,
123+ marginBottom : 8 ,
132124 } }
133- />
134- < Typography variant = "body2" > Critical > 50</ Typography >
135- </ div >
125+ >
126+ < div
127+ style = { {
128+ width : 10 ,
129+ height : 10 ,
130+ backgroundColor :
131+ {
132+ error : 'red' ,
133+ warning : 'orange' ,
134+ success : 'green' ,
135+ } [ key ] || 'green' ,
136+ marginRight : 8 ,
137+ } }
138+ />
139+ < Typography variant = "body2" >
140+ { key } { expression && `${ expression } ` }
141+ </ Typography >
142+ </ div >
143+ ) ) }
136144 </ Box >
137145 </ Box >
138146 </ CardContent >
0 commit comments