diff --git a/priv/frontend/package-lock.json b/priv/frontend/package-lock.json
index 6c332a4..2e81804 100644
--- a/priv/frontend/package-lock.json
+++ b/priv/frontend/package-lock.json
@@ -34,6 +34,18 @@
"prop-types": "^15.5.10"
}
},
+ "@reach/router": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.1.1.tgz",
+ "integrity": "sha1-JKWyDxzJ5V4svNxFT7gslNtHmoE=",
+ "requires": {
+ "create-react-context": "^0.2.1",
+ "invariant": "^2.2.3",
+ "prop-types": "^15.6.1",
+ "react-lifecycles-compat": "^3.0.4",
+ "warning": "^3.0.0"
+ }
+ },
"abab": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
@@ -2258,6 +2270,15 @@
"sha.js": "^2.4.8"
}
},
+ "create-react-context": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz",
+ "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==",
+ "requires": {
+ "fbjs": "^0.8.0",
+ "gud": "^1.0.0"
+ }
+ },
"cross-spawn": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
@@ -4645,6 +4666,11 @@
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE="
},
+ "gud": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
+ "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
+ },
"gzip-size": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz",
@@ -10838,6 +10864,14 @@
"makeerror": "1.0.x"
}
},
+ "warning": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
+ "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"watch": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz",
diff --git a/priv/frontend/package.json b/priv/frontend/package.json
index 894df5f..7755bcb 100644
--- a/priv/frontend/package.json
+++ b/priv/frontend/package.json
@@ -7,6 +7,7 @@
"@fortawesome/fontawesome-svg-core": "^1.2.0-14",
"@fortawesome/free-solid-svg-icons": "^5.1.0-11",
"@fortawesome/react-fontawesome": "0.1.0-11",
+ "@reach/router": "^1.1.1",
"classnames": "^2.2.6",
"ms": "^2.1.1",
"nanoevents": "^1.0.5",
diff --git a/priv/frontend/src/components/App.js b/priv/frontend/src/components/App.js
new file mode 100644
index 0000000..a8b1799
--- /dev/null
+++ b/priv/frontend/src/components/App.js
@@ -0,0 +1,15 @@
+import React from 'react'
+
+import { Router } from '@reach/router'
+
+import Dashboard from './Dashboard'
+import Incidents from './Incidents'
+
+export default function App () {
+ return (
+
+
+
+
+ )
+}
diff --git a/priv/frontend/src/components/Dashboard.js b/priv/frontend/src/components/Dashboard.js
index 8771c07..5aa86d7 100644
--- a/priv/frontend/src/components/Dashboard.js
+++ b/priv/frontend/src/components/Dashboard.js
@@ -1,11 +1,11 @@
import React, { Component } from 'react'
-import './Dashboard.css'
import Service from './Service.js'
import ServicePlaceholder from './ServicePlaceholder.js'
import DegradedNotice from './DegradedNotice.js'
import StreamingClient from '../ws/client'
import Status from './Status'
+import Page from './Page'
import { log, objectFromEntries, strictFetch } from '../util.js'
import { domain as DOMAIN } from '../config.json'
@@ -164,10 +164,10 @@ export default class Dashboard extends Component {
render () {
return (
-
+
elstatus
{this.renderDashboardContent()}
-
+
)
}
}
diff --git a/priv/frontend/src/components/Incident.js b/priv/frontend/src/components/Incident.js
index b61504d..76cf028 100644
--- a/priv/frontend/src/components/Incident.js
+++ b/priv/frontend/src/components/Incident.js
@@ -14,8 +14,13 @@ const OUTAGE_TYPES = {
export default function Incident ({ incident }) {
const { content, end_date: end, start_date: start, title, type, stages } = incident
+
+ const startDate = new Date(start * 1000)
+ const endDate = end ? new Date(end * 1000) : null
+ const tooltip = `Started ${startDate.toLocaleString()}` +
+ (endDate ? `, ended ${endDate.toLocaleString()}` : '')
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
const stageNodes = stages.map(
(stage) =>
@@ -25,7 +30,7 @@ export default function Incident ({ incident }) {
{OUTAGE_TYPES[type] || type}: {title}
{content}
-