Skip to content

Commit

Permalink
feat(webapp): add health indicator to endpoints list
Browse files Browse the repository at this point in the history
- Add endpoints query using new tables
- Temporary mofication of endpointsList components
- Add HealthCheck component
  • Loading branch information
Torresmorah committed Oct 6, 2022
1 parent 38cefd2 commit 2effe9a
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 18 deletions.
36 changes: 36 additions & 0 deletions webapp/src/components/HealthCheck/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react'
import { makeStyles } from '@mui/styles'

import ReportIcon from '@mui/icons-material/Report'
import VerifiedIcon from '@mui/icons-material/Verified'
import TimerOffIcon from '@mui/icons-material/TimerOff'
import WarningIcon from '@mui/icons-material/Warning'

import styles from './styles'

const useStyles = makeStyles(styles)

const HealthCheck = ({children, status}) => {
const classes = useStyles()

const getIcon = (status) => {
switch (status) {
case 'updated':
return <VerifiedIcon className={classes.success}/>
case 'outdated':
return <TimerOffIcon className={classes.timerOff}/>
case 'error':
return <WarningIcon className={classes.warning}/>
default:
return <ReportIcon className={classes.fail}/>
}
}

return (
<div className={classes.icon}>
{status !== undefined && getIcon(status)} {children}
</div>
)
}

export default HealthCheck
20 changes: 20 additions & 0 deletions webapp/src/components/HealthCheck/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default (theme) => ({
icon: {
'& svg': {
width: '16px !important',
height: '16px !important',
}
},
success:{
color: 'darkgreen',
},
timerOff:{
color: 'orange',
},
warning:{
color: 'orangered',
},
fail:{
color: 'darkred',
}
})
32 changes: 32 additions & 0 deletions webapp/src/gql/producer.gql.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,38 @@ export const NODES_QUERY = gql`
}
`

export const ENDPOINTS_QUERY = gql`
query producer(
$offset: Int = 0
$limit: Int = 21
$where: producer_bool_exp
) {
info: producer_aggregate(where: $where) {
producers: aggregate {
count
}
}
producers: producer(
where: $where
order_by: { total_votes_percent: desc }
offset: $offset
limit: $limit
) {
id
owner
updated_at
nodes(where: {type: {_neq: ["producer"]}}){
endpoints(order_by: {head_block_num: desc}){
type
value
head_block_num
response
}
}
}
}
`

export const NODE_CPU_BENCHMARK = gql`
query ($account: String) {
cpu(
Expand Down
43 changes: 32 additions & 11 deletions webapp/src/hooks/customHooks/useEndpointsState.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { useState, useEffect } from 'react'
import { useLazyQuery } from '@apollo/client'

import { PRODUCERS_QUERY } from '../../gql'
import { ENDPOINTS_QUERY } from '../../gql'

const useEndpointsState = () => {
const [load, { loading, data }] = useLazyQuery(PRODUCERS_QUERY)
const [load, { loading, data }] = useLazyQuery(ENDPOINTS_QUERY)
const [producers, setProducers] = useState([])
const [updatedAt, setUpdatedAt] = useState()
const [highestBlockNum, setHighestBlockNum] = useState(0)
const [pagination, setPagination] = useState({
page: 1,
limit: 80,
Expand All @@ -18,7 +19,7 @@ const useEndpointsState = () => {
variables: {
offset: (pagination.page - 1) * pagination.limit,
limit: pagination.limit,
where: { endpoints: { _neq: { api: [], ssl: [], p2p: [] } } },
where: { bp_json: { _has_key: 'nodes' } },
},
})
// eslint-disable-next-line
Expand All @@ -37,16 +38,36 @@ const useEndpointsState = () => {
useEffect(() => {
if (!data?.producers) return

let maxBlockNum = 0

setProducers(
data.producers.map((producer) => ({
name:
producer.bp_json?.org?.candidate_name ||
producer?.bp_json?.org?.organization_name ||
producer?.owner,
endpoints: producer.endpoints,
})),
data.producers.map((producer) => {
const endpoints = { api: [], ssl: [], p2p: [] }

producer.nodes.forEach((node) => {
if (node.endpoints?.length) {
maxBlockNum = Math.max(
maxBlockNum,
node.endpoints[0]?.head_block_num,
)
node.endpoints.forEach(({ type, ...endpoint }) => {
endpoints[type].push(endpoint)
})
}
})

return {
name:
producer.bp_json?.org?.candidate_name ||
producer?.bp_json?.org?.organization_name ||
producer?.owner,
endpoints,
}
}),
)

setHighestBlockNum(maxBlockNum)

if (!data.producers?.[0]?.updated_at) return

setUpdatedAt(data.producers[0].updated_at)
Expand All @@ -61,7 +82,7 @@ const useEndpointsState = () => {
}

return [
{ loading, pagination, producers, updatedAt },
{ loading, pagination, producers, highestBlockNum, updatedAt },
{ handleOnPageChange, setPagination },
]
}
Expand Down
32 changes: 27 additions & 5 deletions webapp/src/routes/EndpointsList/EndpointsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,42 @@ import TableHead from '@mui/material/TableHead'
import TableRow from '@mui/material/TableRow'
import Typography from '@mui/material/Typography'

const EndpointsTable = ({ producers }) => {
import HealthCheck from '../../components/HealthCheck'

const EndpointsTable = ({ producers, blockNum }) => {
const { t } = useTranslation('endpointsListRoute')

const CellList = ({ producer, endpointType }) => {
const getStatus = (endpoint) => {
if(endpoint.response.status === undefined) return

if( endpoint.head_block_num === blockNum ){
return 'updated'
}else{
switch(Math.floor(endpoint.response.status / 100)){
case 2:
return 'outdated'
case 4:
case 5:
return 'error'
default:
return 'not working'
}
}
}

const CellList = ({ producer, endpointType }) => {
return (
<TableCell>
{!producer?.endpoints[endpointType].length ? (
<Typography>N/A</Typography>
) : (
producer.endpoints[endpointType].map((endpoint, index) => (
<Typography key={`${producer?.name}-${endpointType}-${index}`}>
{endpoint}
</Typography>
<HealthCheck
status={getStatus(endpoint)}
key={`${producer?.name}-${endpointType}-${index}`}
>
{endpoint.value}
</HealthCheck>
))
)}
</TableCell>
Expand Down
4 changes: 2 additions & 2 deletions webapp/src/routes/EndpointsList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const EndpointsList = () => {
const classes = useStyles()
const { t } = useTranslation('endpointsListRoute')
const [
{ loading, pagination, producers, updatedAt },
{ loading, pagination, producers, highestBlockNum, updatedAt },
{ handleOnPageChange, setPagination },
] = useEndpointsState()

Expand Down Expand Up @@ -71,7 +71,7 @@ const EndpointsList = () => {
<LinearProgress />
) : (
<>
{!!producers.length && <EndpointsTable producers={producers} />}
{!!producers.length && <EndpointsTable producers={producers} blockNum={highestBlockNum} />}
{pagination.totalPages > 1 && (
<div className={classes.pagination}>
<Pagination
Expand Down

0 comments on commit 2effe9a

Please sign in to comment.