85 lines
1.8 KiB
JavaScript
85 lines
1.8 KiB
JavaScript
import React from 'react'
|
|
import PropTypes from 'prop-types'
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
|
|
import './Service.css'
|
|
import Graph from './Graph.js'
|
|
import config from '../config.json'
|
|
|
|
const {
|
|
slow_threshold: SLOW_THRESHOLD = 1500,
|
|
} = config
|
|
|
|
// from clrs.cc
|
|
const colors = {
|
|
alive: '#2ECC40',
|
|
slow: '#FF851B',
|
|
dead: '#FF4136',
|
|
}
|
|
|
|
const icons = {
|
|
alive: 'check-circle',
|
|
slow: 'exclamation-circle',
|
|
dead: 'times-circle',
|
|
}
|
|
|
|
const titles = {
|
|
alive: 'This service is healthy.',
|
|
slow: 'This service is slow, but responding.',
|
|
dead: 'This service is unresponsive.',
|
|
}
|
|
|
|
function getServiceState (status, latency) {
|
|
if (status && latency > SLOW_THRESHOLD) {
|
|
return 'slow'
|
|
}
|
|
|
|
return status ? 'alive' : 'dead'
|
|
}
|
|
|
|
const Service = ({ graph, name, status, latency, description }) => {
|
|
const state = getServiceState(status, latency)
|
|
|
|
const title = titles[state]
|
|
const icon = icons[state]
|
|
const color = colors[state]
|
|
|
|
return (
|
|
<div className="service">
|
|
<header>
|
|
<div className="emoji" title={title}>
|
|
<FontAwesomeIcon title={title} icon={icon} style={{ color }}/>
|
|
</div>
|
|
<h2 className="title">
|
|
{name} {latency ? (
|
|
<span className="latency">
|
|
{Math.round(latency)}ms
|
|
</span>
|
|
) : null}
|
|
</h2>
|
|
</header>
|
|
<p className="description">
|
|
{description}
|
|
</p>
|
|
{graph ? <Graph data={graph}/> : null}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
Service.defaultProps = {
|
|
graph: null,
|
|
latency: null,
|
|
}
|
|
|
|
Service.propTypes = {
|
|
graph: PropTypes.arrayOf(
|
|
PropTypes.arrayOf(PropTypes.number),
|
|
),
|
|
name: PropTypes.string.isRequired,
|
|
status: PropTypes.bool.isRequired,
|
|
latency: PropTypes.number,
|
|
description: PropTypes.string.isRequired,
|
|
}
|
|
|
|
export default Service
|