@@ -30,6 +30,43 @@ const useStyles = makeStyles(theme => ({
30
30
} ,
31
31
} ) ) ;
32
32
33
+ function InstallPrometheusBanner ( ) {
34
+ const classes = useStyles ( ) ;
35
+ const pluginSettings = usePluginSettings ( ) ;
36
+
37
+ return (
38
+ < Grid
39
+ container
40
+ spacing = { 2 }
41
+ direction = "column"
42
+ justifyContent = "center"
43
+ alignItems = "center"
44
+ className = { classes . skeletonBox }
45
+ >
46
+ < Grid item >
47
+ < Typography variant = "h5" > Install Prometheus for accessing metrics charts</ Typography >
48
+ </ Grid >
49
+ < Grid item >
50
+ < Typography >
51
+ < Link href = { learnMoreLink } target = "_blank" >
52
+ Learn more about enabling advanced charts.
53
+ </ Link >
54
+ </ Typography >
55
+ </ Grid >
56
+ < Grid item >
57
+ < Button
58
+ className = { classes . dismissButton }
59
+ size = "small"
60
+ variant = "contained"
61
+ onClick = { ( ) => pluginSettings . setIsVisible ( false ) }
62
+ >
63
+ Dismiss
64
+ </ Button >
65
+ </ Grid >
66
+ </ Grid >
67
+ )
68
+ }
69
+
33
70
export function GenericMetricsChart ( props : {
34
71
cpuQuery : string ;
35
72
memoryQuery : string ;
@@ -45,7 +82,6 @@ export function GenericMetricsChart(props: {
45
82
INSTALLED ,
46
83
}
47
84
48
- const classes = useStyles ( ) ;
49
85
const pluginSettings = usePluginSettings ( ) ;
50
86
const [ chartVariant , setChartVariant ] = useState < string > ( 'cpu' ) ;
51
87
const [ refresh , setRefresh ] = useState < boolean > ( true ) ;
@@ -160,35 +196,99 @@ export function GenericMetricsChart(props: {
160
196
< Alert severity = "warning" > Error fetching prometheus Info</ Alert >
161
197
</ Box >
162
198
) : (
163
- < Grid
164
- container
165
- spacing = { 2 }
166
- direction = "column"
167
- justifyContent = "center"
168
- alignItems = "center"
169
- className = { classes . skeletonBox }
170
- >
171
- < Grid item >
172
- < Typography variant = "h5" > Install Prometheus for accessing metrics charts</ Typography >
173
- </ Grid >
174
- < Grid item >
175
- < Typography >
176
- < Link href = { learnMoreLink } target = "_blank" >
177
- Learn more about enabling advanced charts.
178
- </ Link >
179
- </ Typography >
180
- </ Grid >
181
- < Grid item >
182
- < Button
183
- className = { classes . dismissButton }
184
- size = "small"
185
- variant = "contained"
186
- onClick = { ( ) => pluginSettings . setIsVisible ( false ) }
187
- >
188
- Dismiss
189
- </ Button >
190
- </ Grid >
191
- </ Grid >
199
+ < InstallPrometheusBanner />
200
+ ) }
201
+ </ SectionBox >
202
+ ) ;
203
+ }
204
+
205
+ export function DiskMetricsChart ( props : {
206
+ usageQuery ?: string ;
207
+ capacityQuery ?: string ;
208
+ } ) {
209
+ enum prometheusState {
210
+ UNKNOWN ,
211
+ LOADING ,
212
+ ERROR ,
213
+ INSTALLED ,
214
+ }
215
+
216
+ const pluginSettings = usePluginSettings ( ) ;
217
+ const [ refresh , setRefresh ] = useState < boolean > ( true ) ;
218
+
219
+ const [ prometheusInfo , setPrometheusInfo ] = useState < {
220
+ podName : string ;
221
+ podNamespace : string ;
222
+ } | null > ( null ) ;
223
+ const [ state , setState ] = useState < prometheusState > ( prometheusState . LOADING ) ;
224
+
225
+ useEffect ( ( ) => {
226
+ ( async ( ) => {
227
+ try {
228
+ const [ isInstalled , podName , namespace ] = await isPrometheusInstalled ( ) ;
229
+ if ( isInstalled ) {
230
+ setPrometheusInfo ( { podName, podNamespace : namespace } ) ;
231
+ setState ( prometheusState . INSTALLED ) ;
232
+ } else {
233
+ setPrometheusInfo ( null ) ;
234
+ setState ( prometheusState . UNKNOWN ) ;
235
+ }
236
+ } catch ( e ) {
237
+ setState ( prometheusState . ERROR ) ;
238
+ return ;
239
+ }
240
+ } ) ( ) ;
241
+ } , [ ] ) ;
242
+
243
+ if ( ! pluginSettings . isVisible ) {
244
+ return null ;
245
+ }
246
+
247
+ return (
248
+ < SectionBox >
249
+ < Box
250
+ display = "flex"
251
+ justifyContent = "space-around"
252
+ alignItems = "center"
253
+ style = { { marginBottom : '0.5rem' , margin : '0 auto' , width : '0%' } }
254
+
255
+ >
256
+ { state === prometheusState . INSTALLED
257
+ ? [
258
+ < Box > Disk</ Box > ,
259
+ < Box pl = { 2 } >
260
+ < IconButton
261
+ onClick = { ( ) => {
262
+ setRefresh ( refresh => ! refresh ) ;
263
+ } }
264
+ size = "Big"
265
+ >
266
+ { refresh ? < Icon icon = "mdi:pause" /> : < Icon icon = "mdi:play" /> }
267
+ </ IconButton >
268
+ </ Box > ,
269
+ ]
270
+ : [ ] }
271
+ </ Box >
272
+
273
+ { prometheusInfo ? (
274
+ < Box style = { { justifyContent : 'center' , display : 'flex' , height : '40vh' , width : '80%' , margin : '0 auto' } } >
275
+ < DiskChart
276
+ usageQuery = { props . usageQuery }
277
+ capacityQuery = { props . capacityQuery }
278
+ autoRefresh = { refresh }
279
+ prometheusPrefix = { `${ prometheusInfo . podNamespace } /pods/${ prometheusInfo . podName } ` }
280
+ />
281
+ </ Box >
282
+ ) : state === prometheusState . LOADING ? (
283
+ < Box m = { 2 } >
284
+ < Loader title = "Loading Prometheus Info" />
285
+ </ Box >
286
+ ) : state === prometheusState . ERROR ? (
287
+ < Box m = { 2 } >
288
+ < Alert severity = "warning" > Error fetching prometheus Info</ Alert >
289
+ </ Box >
290
+ ) : (
291
+ < InstallPrometheusBanner />
192
292
) }
193
293
</ SectionBox >
194
294
) ;
@@ -442,6 +542,70 @@ export function NetworkChart(props: {
442
542
) ;
443
543
}
444
544
545
+ export function DiskChart ( props : {
546
+ usageQuery : string ;
547
+ capacityQuery : string ;
548
+ prometheusPrefix : string ;
549
+ autoRefresh : boolean ;
550
+ } ) {
551
+ const xTickFormatter = createTickTimestampFormatter ( ) ;
552
+ const theme = useTheme ( ) ;
553
+
554
+ return (
555
+ < Chart
556
+ plots = { [
557
+ {
558
+ query : props . usageQuery ,
559
+ name : 'usage' ,
560
+ strokeColor : '#CDC300' ,
561
+ fillColor : '#FFF178' ,
562
+ dataProcessor : dataProcessor ,
563
+ } ,
564
+ {
565
+ query : props . capacityQuery ,
566
+ name : 'capacity' ,
567
+ strokeColor : '#006B58' ,
568
+ fillColor : '#98F6DC' ,
569
+ dataProcessor : dataProcessor ,
570
+ } ,
571
+ ] }
572
+ xAxisProps = { {
573
+ dataKey : 'timestamp' ,
574
+ tickLine : false ,
575
+ tick : props => {
576
+ const value = xTickFormatter ( props . payload . value ) ;
577
+ return (
578
+ value !== '' && (
579
+ < g
580
+ transform = { `translate(${ props . x } ,${ props . y } )` }
581
+ fill = { theme . palette . chartStyles . labelColor }
582
+ >
583
+ < text x = { 0 } y = { 10 } dy = { 0 } textAnchor = "middle" >
584
+ { value }
585
+ </ text >
586
+ </ g >
587
+ )
588
+ ) ;
589
+ } ,
590
+ } }
591
+ yAxisProps = { {
592
+ domain : [ 'dataMin' , 'auto' ] ,
593
+ tick : ( { x, y, payload } ) => (
594
+ < g transform = { `translate(${ x } ,${ y } )` } fill = { theme . palette . chartStyles . labelColor } >
595
+ < text x = { - 35 } y = { 0 } dy = { 0 } textAnchor = "middle" >
596
+ { formatBytes ( payload . value ) }
597
+ </ text >
598
+ </ g >
599
+ ) ,
600
+ width : 80 ,
601
+ } }
602
+ fetchMetrics = { fetchMetrics }
603
+ CustomTooltip = { CustomTooltipFormatBytes }
604
+ { ...props }
605
+ />
606
+ ) ;
607
+ }
608
+
445
609
export function FilesystemChart ( props : {
446
610
readQuery : string ;
447
611
writeQuery : string ;
0 commit comments