general code cleanup/refactoring
This commit is contained in:
parent
4a0ed13180
commit
1dab3ccd0b
8 changed files with 104 additions and 82 deletions
|
@ -35,6 +35,7 @@ export default class Dashboard extends Component {
|
|||
const endpoint = `${DOMAIN}/api/streaming`
|
||||
.replace('https', 'wss')
|
||||
.replace('http', 'ws')
|
||||
|
||||
this.client = new StreamingClient(endpoint, this.state.metrics)
|
||||
this.client.connect()
|
||||
|
||||
|
@ -110,50 +111,62 @@ export default class Dashboard extends Component {
|
|||
this.setState({ incident: await resp.json() })
|
||||
}
|
||||
|
||||
render () {
|
||||
let metrics = null
|
||||
renderNotice (services) {
|
||||
const down = services.filter(([, { status }]) => !status)
|
||||
|
||||
if (this.state.metrics) {
|
||||
const allServices = Object.entries(this.state.metrics.status)
|
||||
const graphs = this.state.metrics.graph
|
||||
// DegradedNotice should only be shown when there is no ongoing incident,
|
||||
// and any services are reported as down.
|
||||
if (!this.state.incident && down.length > 0) {
|
||||
return <DegradedNotice services={objectFromEntries(down)}/>
|
||||
}
|
||||
|
||||
const services = allServices.map(([name, info]) => (
|
||||
return <Status incident={this.state.incident}/>
|
||||
}
|
||||
|
||||
renderServices (services) {
|
||||
const { graph: graphs } = this.state.metrics
|
||||
return services.map(([name, info]) => (
|
||||
<Service name={name} key={name} graph={graphs[name]} {...info}/>
|
||||
))
|
||||
|
||||
const down = allServices.filter(([, { status }]) => !status)
|
||||
let notice = <Status incident={this.state.incident}/>
|
||||
if (!this.state.incident && down.length > 0) {
|
||||
notice = down.length > 0
|
||||
? <DegradedNotice services={objectFromEntries(down)}/>
|
||||
: null
|
||||
}
|
||||
|
||||
metrics = (
|
||||
<div className="services">
|
||||
{notice}
|
||||
{services}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderPlaceholders () {
|
||||
return (
|
||||
<div className="dashboard">
|
||||
<h1>elstatus</h1>
|
||||
|
||||
{this.state.error ? (
|
||||
<div className="error">
|
||||
{this.state.error}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{this.state.loading && !this.state.error ? (
|
||||
<React.Fragment>
|
||||
<ServicePlaceholder/>
|
||||
<ServicePlaceholder/>
|
||||
<ServicePlaceholder/>
|
||||
</React.Fragment>
|
||||
) : metrics}
|
||||
)
|
||||
}
|
||||
|
||||
renderDashboardContent () {
|
||||
if (this.state.error) {
|
||||
return <div className="error">{this.state.error}</div>
|
||||
}
|
||||
|
||||
if (this.state.loading) {
|
||||
return this.renderPlaceholders()
|
||||
}
|
||||
|
||||
const allServices = Object.entries(this.state.metrics.status)
|
||||
|
||||
const services = this.renderServices(allServices)
|
||||
const notice = this.renderNotice(allServices)
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{notice}
|
||||
{services}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className="dashboard">
|
||||
<h1>elstatus</h1>
|
||||
{this.renderDashboardContent()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
|||
|
||||
import './DegradedNotice.css'
|
||||
|
||||
const DegradedNotice = ({ services }) => {
|
||||
export default function DegradedNotice ({ services }) {
|
||||
const keys = Object.keys(services)
|
||||
const serviceNames = keys.join(', ')
|
||||
|
||||
|
@ -23,5 +23,3 @@ const DegradedNotice = ({ services }) => {
|
|||
DegradedNotice.propTypes = {
|
||||
services: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
export default DegradedNotice
|
||||
|
|
|
@ -12,7 +12,7 @@ const OUTAGE_TYPES = {
|
|||
degraded_service: 'Degraded Service',
|
||||
}
|
||||
|
||||
const Incident = ({ incident }) => {
|
||||
export default function Incident ({ incident }) {
|
||||
const { content, end_date: end, start_date: start, title, type, stages } = incident
|
||||
const ago = ms(Date.now() - start * 1000)
|
||||
const agoEnd = end ? ms(Date.now - end * 1000) : null
|
||||
|
@ -51,5 +51,3 @@ Incident.propTypes = {
|
|||
stages: PropTypes.array,
|
||||
}),
|
||||
}
|
||||
|
||||
export default Incident
|
||||
|
|
|
@ -38,7 +38,7 @@ function getServiceState (status, latency) {
|
|||
return status ? 'alive' : 'dead'
|
||||
}
|
||||
|
||||
const Service = ({ graph, name, status, latency, description }) => {
|
||||
export default function Service ({ graph, name, status, latency, description }) {
|
||||
const state = getServiceState(status, latency)
|
||||
|
||||
const title = titles[state]
|
||||
|
@ -81,5 +81,3 @@ Service.propTypes = {
|
|||
latency: PropTypes.number,
|
||||
description: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
export default Service
|
||||
|
|
|
@ -7,3 +7,23 @@
|
|||
grid-template-columns: 3rem 1fr;
|
||||
grid-gap: 1rem;
|
||||
}
|
||||
|
||||
.service-placeholder .emoji {
|
||||
width: 3rem !important;
|
||||
height: 3rem !important;
|
||||
}
|
||||
|
||||
.service-placeholder .name {
|
||||
width: 100% !important;
|
||||
height: 3rem !important;
|
||||
}
|
||||
|
||||
.service-placeholder .text {
|
||||
margin-top: 1rem !important;
|
||||
}
|
||||
|
||||
.service-placeholder .graph {
|
||||
width: 100% !important;
|
||||
height: 175px !important;
|
||||
margin-top: 1rem !important;
|
||||
}
|
||||
|
|
|
@ -5,23 +5,23 @@ import 'react-placeholder/lib/reactPlaceholder.css'
|
|||
|
||||
import './ServicePlaceholder.css'
|
||||
|
||||
const ServicePlaceholder = () => (
|
||||
export default function ServicePlaceholder () {
|
||||
return (
|
||||
<div className="service-placeholder">
|
||||
<div className="title">
|
||||
<ReactPlaceholder
|
||||
type="round"
|
||||
ready={false}
|
||||
style={{ width: '3rem', height: '3rem' }}
|
||||
className="emoji"
|
||||
showLoadingAnimation
|
||||
className="emoji"
|
||||
>
|
||||
{' '}
|
||||
</ReactPlaceholder>
|
||||
<ReactPlaceholder
|
||||
type="rect"
|
||||
ready={false}
|
||||
style={{ width: '100%', height: '3rem' }}
|
||||
showLoadingAnimation
|
||||
className="name"
|
||||
>
|
||||
{' '}
|
||||
</ReactPlaceholder>
|
||||
|
@ -30,20 +30,19 @@ const ServicePlaceholder = () => (
|
|||
type="text"
|
||||
ready={false}
|
||||
rows={1}
|
||||
style={{ marginTop: '1rem' }}
|
||||
showLoadingAnimation
|
||||
className="text"
|
||||
>
|
||||
{' '}
|
||||
</ReactPlaceholder>
|
||||
<ReactPlaceholder
|
||||
type="rect"
|
||||
ready={false}
|
||||
style={{ width: '100%', height: '175px', marginTop: '1rem' }}
|
||||
showLoadingAnimation
|
||||
className="graph"
|
||||
>
|
||||
{' '}
|
||||
</ReactPlaceholder>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default ServicePlaceholder
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
|||
|
||||
import ms from 'ms'
|
||||
|
||||
const Stage = ({ stage }) => {
|
||||
export default function Stage ({ stage }) {
|
||||
const { created_at: createdAt, title, content } = stage
|
||||
const ago = ms(Date.now() - createdAt * 1000)
|
||||
|
||||
|
@ -21,7 +21,5 @@ Stage.propTypes = {
|
|||
created_at: PropTypes.number,
|
||||
title: PropTypes.string,
|
||||
content: PropTypes.string,
|
||||
})
|
||||
}),
|
||||
}
|
||||
|
||||
export default Stage
|
||||
|
|
|
@ -5,7 +5,7 @@ import classnames from 'classnames'
|
|||
import './Status.css'
|
||||
import Incident from './Incident'
|
||||
|
||||
const Status = ({ incident }) => {
|
||||
export default function Status ({ incident }) {
|
||||
let view = null
|
||||
if (incident) {
|
||||
view = <Incident incident={incident}/>
|
||||
|
@ -27,5 +27,3 @@ const Status = ({ incident }) => {
|
|||
Status.propTypes = {
|
||||
incident: PropTypes.object,
|
||||
}
|
||||
|
||||
export default Status
|
||||
|
|
Loading…
Reference in a new issue