diff options
Diffstat (limited to 'webui/src')
-rw-r--r-- | webui/src/Components/Timeline/EventNode.js | 82 | ||||
-rw-r--r-- | webui/src/Event.js | 88 | ||||
-rw-r--r-- | webui/src/Timeline.js | 154 |
3 files changed, 219 insertions, 105 deletions
diff --git a/webui/src/Components/Timeline/EventNode.js b/webui/src/Components/Timeline/EventNode.js index 9e7bebc..74022a7 100644 --- a/webui/src/Components/Timeline/EventNode.js +++ b/webui/src/Components/Timeline/EventNode.js @@ -1,103 +1,31 @@ import React, { Component } from 'react'; import './EventNode.scss'; -import moment from 'moment'; class EventNode extends Component { - getColorClass() { - - if(this.props.event.type === "StartupEvent") - return "green"; - - if(this.props.event.type === "WebhookAction") - return "blue"; - - return "purple"; - } - - getTitle() { - - if(this.props.event.type === "StartupEvent") - return "Startup"; - - if(this.props.event.type === "WebhookAction") - return "Webhook"; - - return this.props.event.type; - } - - getSubtitle() { - - if(this.props.event.type === "StartupEvent") { - - if(this.isWaiting()) - return "Starting up.." - - return "Listening for incoming connections"; - } - - if(this.props.event.type === "WebhookAction") { - if(this.props.event.messages.length) - return this.props.event.messages[this.props.event.messages.length - 1] - return "Incoming request from " + this.props.event['client-address']; - } - - return this.props.event.type; - } - - getDate() { - return moment.unix(this.props.event.timestamp).format("YYYY-MM-DD"); - } - - getTime() { - return moment.unix(this.props.event.timestamp).format("HH:mm"); - } - - getIconName() { - - if(this.props.event.success === false) - return "alert" - - if(this.props.event.type === "StartupEvent") - return "alert-circle"; - - return "check"; - } - - isWaiting() { - if(this.props.event.type === "StartupEvent") { - if(this.props.event['ws-started'] !== true || this.props.event['http-started'] !== true) { - return true; - } - } else if(this.props.event.waiting === true) { - return true; - } - return false; - } - getIconElement() { - if(this.isWaiting()) { + if(this.props.event.isWaiting()) { return ( <div className="icon spinner"></div> ); } return ( - <i className={"icon mdi mdi-" + this.getIconName()} /> + <i className={"icon mdi mdi-" + this.props.event.getIconName()} /> ); } render() { return ( - <div className={"EventNode " + this.props.alignment + " " + this.getColorClass()}> + <div className={"EventNode " + this.props.alignment + " " + this.props.event.getColorClass()}> <span className="horizontal-line"></span> <span className="timeline-icon"></span> <div className="inner"> <div className="header"> {this.getIconElement()} - <p className="title">{this.getTitle()}</p> - <p className="subtitle">{this.getSubtitle()}</p> + <p className="title">{this.props.event.getTitle()}</p> + <p className="subtitle">{this.props.event.getSubtitle()}</p> </div> <div className="body"> {this.props.children} diff --git a/webui/src/Event.js b/webui/src/Event.js new file mode 100644 index 0000000..f74908d --- /dev/null +++ b/webui/src/Event.js @@ -0,0 +1,88 @@ +import moment from 'moment'; + +class Event { + + constructor(event) { + var self = this; + self.event = event; + + for(var key in event) { + if(!event.hasOwnProperty(key)) + continue; + self[key] = event[key]; + } + } + + getColorClass() { + + if(this.event.type === "StartupEvent") + return "green"; + + if(this.event.type === "WebhookAction") + return "blue"; + + return "purple"; + } + + getTitle() { + + if(this.event.type === "StartupEvent") + return "Startup"; + + if(this.event.type === "WebhookAction") + return "Webhook"; + + return this.event.type; + } + + getSubtitle() { + + if(this.event.type === "StartupEvent") { + + if(this.isWaiting()) + return "Starting up.." + + return "Listening for incoming connections"; + } + + if(this.event.type === "WebhookAction") { + if(this.event.messages.length) + return this.event.messages[this.event.messages.length - 1] + return "Incoming request from " + this.event['client-address']; + } + + return this.event.type; + } + + getDate() { + return moment.unix(this.event.timestamp).format("YYYY-MM-DD"); + } + + getTime() { + return moment.unix(this.event.timestamp).format("HH:mm"); + } + + getIconName() { + + if(this.event.success === false) + return "alert" + + if(this.event.type === "StartupEvent") + return "alert-circle"; + + return "check"; + } + + isWaiting() { + if(this.event.type === "StartupEvent") { + if(this.event['ws-started'] !== true || this.event['http-started'] !== true) { + return true; + } + } else if(this.event.waiting === true) { + return true; + } + return false; + } +} + +export default Event; diff --git a/webui/src/Timeline.js b/webui/src/Timeline.js index bf35994..6e97842 100644 --- a/webui/src/Timeline.js +++ b/webui/src/Timeline.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import './Timeline.scss'; import axios from 'axios'; +import Event from './Event'; import EventNode from './Components/Timeline/EventNode'; import DateNode from './Components/Timeline/DateNode'; import EndNode from './Components/Timeline/EndNode'; @@ -23,6 +24,61 @@ class Timeline extends Component { componentDidMount() { this.fetchEventList(); this.initWebsocketConnection(); + this.initUserNotification(); + } + + initUserNotification() { + if(!('Notification' in window)) + return; + + // Not yet approved? + if (Notification.permission === 'default') { + + // Request permission + return Notification.requestPermission(function() { + //console.log("Got permission!"); + }); + } + } + + showUserNotification(event) { + + if(!('Notification' in window)) + return; + + if(Notification.permission !== "granted") + return; + + // define new notification + var n = new Notification( + event.getSubtitle(), + { + 'body': event.getTitle(), + 'tag' : "event-" + event.id + } + ); + + // notify when shown successfull + n.onshow = function () { + console.log("onshow"); + }; + + // remove the notification from Notification Center when clicked. + n.onclick = function () { + this.close(); + console.log("onclick"); + }; + + // callback function when the notification is closed. + n.onclose = function () { + console.log("onclose"); + }; + + // notification cannot be presented to the user, this event is fired if the permission level is set to denied or default. + n.onerror = function () { + console.log("onerror"); + }; + } fetchEventList() { @@ -41,7 +97,7 @@ class Timeline extends Component { { //obj.key = obj.id; //console.log(obj); - return obj; + return new Event(obj); } ); this.setState({ events: events, loaded: true }); @@ -52,48 +108,90 @@ class Timeline extends Component { } + addOrUpdateEvent(event) { + + this.setState((prevState, props) => { + + var newEvents = []; + var inserted = false; + + for(var key in prevState.events) { + if(prevState.hasOwnProperty(key)) + continue; + var curEvent = prevState.events[key]; + + if(curEvent.id === event.id) { + newEvents.push(event); + inserted = true; + } else { + newEvents.push(curEvent); + } + } + + if(!inserted) { + newEvents.push(event); + } + + return { + events: newEvents + } + + }); + } + + getEventWithId(id) { + var self = this; + + for(var key in self.state.events) { + + if(self.state.hasOwnProperty(key)) + continue; + + var event = self.state.events[key]; + + if(event.id === id) + return event; + + } + + return undefined; + } + handleJSONMessage(data) { - if(data.type === "event-update") { + var event; - this.setState((prevState, props) => { + if(data.type === "new-event") { - var newEvents = []; - var inserted = false; + event = new Event(data.event); + this.addOrUpdateEvent(event); - for(var key in prevState.events) { - if(prevState.hasOwnProperty(key)) - continue; - var event = prevState.events[key]; + } else if(data.type === "event-updated") { - if(event.id === data.event.id) { - newEvents.push(data.event); - inserted = true; - } else { - newEvents.push(event); - } - } + event = new Event(data.event); + this.addOrUpdateEvent(event); - if(!inserted) { - newEvents.push(data.event); - } + } else if(data.type === "event-success") { - return { - events: newEvents - } - - }); + event = this.getEventWithId(data.id); + + if(event && event.type === "WebhookAction") { + + this.showUserNotification(event); + + } } else { - console.log("Unknown event"); - console.log(data); + + console.log("Unknown event: " + data.type); + } } initWebsocketConnection() { var self = this; - var scheme = window.location.protocol == "https" ? "wss" : "ws"; + var scheme = window.location.protocol === "https" ? "wss" : "ws"; var uri = scheme + "://" + window.location.hostname + ":9000"; if (process.env.NODE_ENV === "development") { @@ -104,7 +202,7 @@ class Timeline extends Component { this.wsSocket.binaryType = "arraybuffer"; this.wsSocket.onopen = function() { - console.log("Connected!"); + //console.log("Connected!"); this.wsIsOpen = true; } |