general code cleanup/refactoring

This commit is contained in:
slice 2018-07-18 17:48:16 -07:00
parent 4a0ed13180
commit 1dab3ccd0b
No known key found for this signature in database
GPG Key ID: 1508C19D7436A26D
8 changed files with 104 additions and 82 deletions

View File

@ -35,6 +35,7 @@ export default class Dashboard extends Component {
const endpoint = `${DOMAIN}/api/streaming` const endpoint = `${DOMAIN}/api/streaming`
.replace('https', 'wss') .replace('https', 'wss')
.replace('http', 'ws') .replace('http', 'ws')
this.client = new StreamingClient(endpoint, this.state.metrics) this.client = new StreamingClient(endpoint, this.state.metrics)
this.client.connect() this.client.connect()
@ -110,50 +111,62 @@ export default class Dashboard extends Component {
this.setState({ incident: await resp.json() }) this.setState({ incident: await resp.json() })
} }
render () { renderNotice (services) {
let metrics = null const down = services.filter(([, { status }]) => !status)
if (this.state.metrics) { // DegradedNotice should only be shown when there is no ongoing incident,
const allServices = Object.entries(this.state.metrics.status) // and any services are reported as down.
const graphs = this.state.metrics.graph if (!this.state.incident && down.length > 0) {
return <DegradedNotice services={objectFromEntries(down)}/>
const services = allServices.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>
)
} }
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}/>
))
}
renderPlaceholders () {
return (
<React.Fragment>
<ServicePlaceholder/>
<ServicePlaceholder/>
<ServicePlaceholder/>
</React.Fragment>
)
}
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 ( return (
<div className="dashboard"> <div className="dashboard">
<h1>elstatus</h1> <h1>elstatus</h1>
{this.renderDashboardContent()}
{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}
</div> </div>
) )
} }

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import './DegradedNotice.css' import './DegradedNotice.css'
const DegradedNotice = ({ services }) => { export default function DegradedNotice ({ services }) {
const keys = Object.keys(services) const keys = Object.keys(services)
const serviceNames = keys.join(', ') const serviceNames = keys.join(', ')
@ -23,5 +23,3 @@ const DegradedNotice = ({ services }) => {
DegradedNotice.propTypes = { DegradedNotice.propTypes = {
services: PropTypes.object.isRequired, services: PropTypes.object.isRequired,
} }
export default DegradedNotice

View File

@ -12,7 +12,7 @@ const OUTAGE_TYPES = {
degraded_service: 'Degraded Service', 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 { content, end_date: end, start_date: start, title, type, stages } = incident
const ago = ms(Date.now() - start * 1000) const ago = ms(Date.now() - start * 1000)
const agoEnd = end ? ms(Date.now - end * 1000) : null const agoEnd = end ? ms(Date.now - end * 1000) : null
@ -51,5 +51,3 @@ Incident.propTypes = {
stages: PropTypes.array, stages: PropTypes.array,
}), }),
} }
export default Incident

View File

@ -38,7 +38,7 @@ function getServiceState (status, latency) {
return status ? 'alive' : 'dead' 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 state = getServiceState(status, latency)
const title = titles[state] const title = titles[state]
@ -81,5 +81,3 @@ Service.propTypes = {
latency: PropTypes.number, latency: PropTypes.number,
description: PropTypes.string.isRequired, description: PropTypes.string.isRequired,
} }
export default Service

View File

@ -7,3 +7,23 @@
grid-template-columns: 3rem 1fr; grid-template-columns: 3rem 1fr;
grid-gap: 1rem; 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;
}

View File

@ -5,45 +5,44 @@ import 'react-placeholder/lib/reactPlaceholder.css'
import './ServicePlaceholder.css' import './ServicePlaceholder.css'
const ServicePlaceholder = () => ( export default function ServicePlaceholder () {
<div className="service-placeholder"> return (
<div className="title"> <div className="service-placeholder">
<div className="title">
<ReactPlaceholder
type="round"
ready={false}
showLoadingAnimation
className="emoji"
>
{' '}
</ReactPlaceholder>
<ReactPlaceholder
type="rect"
ready={false}
showLoadingAnimation
className="name"
>
{' '}
</ReactPlaceholder>
</div>
<ReactPlaceholder <ReactPlaceholder
type="round" type="text"
ready={false} ready={false}
style={{ width: '3rem', height: '3rem' }} rows={1}
className="emoji"
showLoadingAnimation showLoadingAnimation
className="text"
> >
{' '} {' '}
</ReactPlaceholder> </ReactPlaceholder>
<ReactPlaceholder <ReactPlaceholder
type="rect" type="rect"
ready={false} ready={false}
style={{ width: '100%', height: '3rem' }}
showLoadingAnimation showLoadingAnimation
className="graph"
> >
{' '} {' '}
</ReactPlaceholder> </ReactPlaceholder>
</div> </div>
<ReactPlaceholder )
type="text" }
ready={false}
rows={1}
style={{ marginTop: '1rem' }}
showLoadingAnimation
>
{' '}
</ReactPlaceholder>
<ReactPlaceholder
type="rect"
ready={false}
style={{ width: '100%', height: '175px', marginTop: '1rem' }}
showLoadingAnimation
>
{' '}
</ReactPlaceholder>
</div>
)
export default ServicePlaceholder

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import ms from 'ms' import ms from 'ms'
const Stage = ({ stage }) => { export default function Stage ({ stage }) {
const { created_at: createdAt, title, content } = stage const { created_at: createdAt, title, content } = stage
const ago = ms(Date.now() - createdAt * 1000) const ago = ms(Date.now() - createdAt * 1000)
@ -21,7 +21,5 @@ Stage.propTypes = {
created_at: PropTypes.number, created_at: PropTypes.number,
title: PropTypes.string, title: PropTypes.string,
content: PropTypes.string, content: PropTypes.string,
}) }),
} }
export default Stage

View File

@ -5,7 +5,7 @@ import classnames from 'classnames'
import './Status.css' import './Status.css'
import Incident from './Incident' import Incident from './Incident'
const Status = ({ incident }) => { export default function Status ({ incident }) {
let view = null let view = null
if (incident) { if (incident) {
view = <Incident incident={incident}/> view = <Incident incident={incident}/>
@ -27,5 +27,3 @@ const Status = ({ incident }) => {
Status.propTypes = { Status.propTypes = {
incident: PropTypes.object, incident: PropTypes.object,
} }
export default Status