1
- import React from "react" ;
1
+ import React , { useState , useEffect } from "react" ;
2
2
import PropTypes from "prop-types" ;
3
3
import "./RankingTable.css" ;
4
4
5
5
const RankingTable = ( { orchestrators, selectedKPI } ) => {
6
+ const [ selectedRegion , setSelectedRegion ] = useState ( "global" ) ;
7
+
8
+ // Set initial position once when parentRef becomes available
9
+ useEffect ( ( ) => {
10
+ setSelectedRegion ( "global" ) ;
11
+ } , [ selectedKPI ] ) ;
12
+
6
13
const kpiLabel = {
7
14
avgPrice : "Price" ,
8
15
avgDiscoveryTime : "Discovery Time" ,
9
- avgRTR : "Realtime ratio " ,
16
+ avgRTR : "Realtime Ratio " ,
10
17
} ;
11
18
12
- // Validate data
13
- const validOrchestrators = orchestrators . filter ( ( orch ) =>
14
- orch [ selectedKPI ] !== undefined && orch [ selectedKPI ] > 0.0
15
- ) ;
19
+ // Extract unique regions for dropdown options
20
+ const uniqueRegions = [
21
+ "global" ,
22
+ ...new Set (
23
+ orchestrators . flatMap ( ( orch ) =>
24
+ orch . instances . flatMap ( ( instance ) => {
25
+ if ( selectedKPI === "avgRTR" ) {
26
+ return instance . livepeer_regions ;
27
+ } else {
28
+ return instance . regions ;
29
+
30
+ }
31
+ }
32
+ )
33
+ )
34
+ ) ,
35
+ ] ;
36
+
37
+ // Handle dropdown change
38
+ const handleRegionChange = ( event ) => {
39
+ setSelectedRegion ( event . target . value ) ;
40
+ } ;
41
+
42
+ // Validate and filter orchestrators based on the selected KPI and region
43
+ const validOrchestrators = orchestrators . filter ( ( orch ) => {
44
+ // If global, return all orchestrators with valid KPI values
45
+ if ( selectedRegion === "global" ) {
46
+ return orch [ selectedKPI ] !== undefined && orch [ selectedKPI ] > 0.0 ;
47
+ }
48
+
49
+ // If filtering by specific region
50
+ return orch . instances . some ( ( instance ) => {
51
+ if ( selectedKPI === "avgRTR" ) {
52
+ return (
53
+ instance . livepeer_regions . includes ( selectedRegion ) &&
54
+ instance . avgRTRByRegion [ selectedRegion ] !== undefined &&
55
+ instance . avgRTRByRegion [ selectedRegion ] > 0.0
56
+ ) ;
57
+ } else {
58
+ return (
59
+ instance . regions . includes ( selectedRegion ) &&
60
+ instance . avgPriceByRegion [ selectedRegion ] !== undefined &&
61
+ instance . avgPriceByRegion [ selectedRegion ] > 0.0
62
+ ) ;
63
+ }
64
+ } ) ;
65
+ } ) ;
16
66
17
67
const sortedOrchestrators = [ ...validOrchestrators ] . sort ( ( a , b ) => {
18
68
const valueA = a [ selectedKPI ] >= 0 ? a [ selectedKPI ] : Infinity ;
@@ -23,6 +73,19 @@ const RankingTable = ({ orchestrators, selectedKPI }) => {
23
73
return (
24
74
< div className = "ranking-table" >
25
75
< h4 > Ranking Table</ h4 >
76
+
77
+ { /* Dropdown for Region Selection */ }
78
+ < div className = "region-selector" >
79
+ < label htmlFor = "region-select" > Select Region:</ label >
80
+ < select id = "region-select" value = { selectedRegion } onChange = { handleRegionChange } >
81
+ { uniqueRegions . map ( ( region ) => (
82
+ < option key = { region } value = { region } >
83
+ { region }
84
+ </ option >
85
+ ) ) }
86
+ </ select >
87
+ </ div >
88
+
26
89
< table >
27
90
< thead >
28
91
< tr >
@@ -32,15 +95,33 @@ const RankingTable = ({ orchestrators, selectedKPI }) => {
32
95
</ tr >
33
96
</ thead >
34
97
< tbody >
35
- { sortedOrchestrators . map ( ( orchestrator , index ) => (
36
- < tr key = { orchestrator . id } >
37
- < td > { index + 1 } </ td >
38
- < td > { orchestrator . name } </ td >
39
- < td >
40
- { orchestrator [ selectedKPI ] >= 0 ? orchestrator [ selectedKPI ] ?. toFixed ( 2 ) || 0 : "?" }
41
- </ td >
42
- </ tr >
43
- ) ) }
98
+ { sortedOrchestrators . map ( ( orchestrator , index ) => {
99
+ // Determine which value to display based on selected region
100
+ let value = 0 ;
101
+
102
+ if ( selectedRegion === "global" ) {
103
+ value = orchestrator [ selectedKPI ] ;
104
+ } else {
105
+ const instance = orchestrator . instances . find ( ( inst ) =>
106
+ selectedKPI === "avgRTR"
107
+ ? inst . livepeer_regions . includes ( selectedRegion )
108
+ : inst . regions . includes ( selectedRegion )
109
+ ) ;
110
+ if ( instance ) {
111
+ value = selectedKPI === "avgRTR"
112
+ ? instance . avgRTRByRegion [ selectedRegion ]
113
+ : instance . avgPriceByRegion [ selectedRegion ] ;
114
+ }
115
+ }
116
+
117
+ return (
118
+ < tr key = { orchestrator . id } >
119
+ < td > { index + 1 } </ td >
120
+ < td > { orchestrator . name } </ td >
121
+ < td > { value >= 0 ? value ?. toFixed ( 2 ) || 0 : "?" } </ td >
122
+ </ tr >
123
+ ) ;
124
+ } ) }
44
125
</ tbody >
45
126
</ table >
46
127
</ div >
@@ -56,6 +137,18 @@ RankingTable.propTypes = {
56
137
avgDiscoveryTime : PropTypes . number ,
57
138
avgRTR : PropTypes . number ,
58
139
avgSR : PropTypes . number ,
140
+ instances : PropTypes . arrayOf (
141
+ PropTypes . shape ( {
142
+ id : PropTypes . string . isRequired ,
143
+ regions : PropTypes . arrayOf ( PropTypes . string ) . isRequired ,
144
+ livepeer_regions : PropTypes . arrayOf ( PropTypes . string ) . isRequired ,
145
+ price : PropTypes . number ,
146
+ avgRTR : PropTypes . number ,
147
+ avgPriceByRegion : PropTypes . object ,
148
+ avgDiscoveryTimeByRegion : PropTypes . object ,
149
+ avgRTRByRegion : PropTypes . object ,
150
+ } )
151
+ ) . isRequired ,
59
152
} )
60
153
) . isRequired ,
61
154
selectedKPI : PropTypes . oneOf ( [ "avgPrice" , "avgDiscoveryTime" , "avgRTR" ] ) . isRequired ,
0 commit comments