From a125b6756a0803a692051d859f54b98be76e3e67 Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Fri, 1 Feb 2019 21:32:45 +0000 Subject: [PATCH] Initial Prometheus expression browser code Signed-off-by: Julius Volz --- src/App.css | 32 -------- src/App.js | 177 ++++++++++++++++++++++++++++++++++++++----- src/index.css | 14 ---- src/index.js | 7 -- src/logo.svg | 7 -- src/serviceWorker.js | 135 --------------------------------- 6 files changed, 160 insertions(+), 212 deletions(-) delete mode 100755 src/App.css delete mode 100755 src/index.css delete mode 100755 src/logo.svg delete mode 100755 src/serviceWorker.js diff --git a/src/App.css b/src/App.css deleted file mode 100755 index 92f956e804..0000000000 --- a/src/App.css +++ /dev/null @@ -1,32 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - animation: App-logo-spin infinite 20s linear; - height: 40vmin; -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/src/App.js b/src/App.js index 7e261ca47e..9c723ac188 100755 --- a/src/App.js +++ b/src/App.js @@ -1,28 +1,171 @@ import React, { Component } from 'react'; -import logo from './logo.svg'; -import './App.css'; class App extends Component { render() { return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
+ + ); + } +} + +class PanelList extends Component { + constructor(props) { + super(props); + this.state = { + panels: [], + }; + this.key = 0; + + this.addPanel = this.addPanel.bind(this); + this.removePanel = this.removePanel.bind(this); + } + + componentDidMount() { + this.addPanel(); + } + + getKey() { + return (this.key++).toString(); + } + + addPanel() { + const panels = this.state.panels.slice(); + const key = this.getKey(); + panels.push( this.removePanel(key)}/>); + this.setState({panels: panels}); + } + + removePanel(key) { + const panels = this.state.panels.filter(panel => { + return panel.key !== key; + }); + this.setState({panels: panels}); + } + + render() { + return ( + <> + {this.state.panels} + + + ); + } +} + +class Panel extends Component { + constructor(props) { + super(props); + + this.state = { + expr: '', + type: 'graph', // TODO enum? + range: '1h', + endTime: null, + data: null, + loading: false, + error: null, + stats: null, + }; + + this.execute = this.execute.bind(this); + this.handleExpressionChange = this.handleExpressionChange.bind(this); + } + + execute() { + this.setState({loading: true}); + + fetch('http://demo.robustperception.io:9090/api/v1/query?query=' + encodeURIComponent(this.state.expr)) + .then(resp => { + if (resp.ok) { + return resp.json(); + } else { + console.log(resp); + throw new Error('Unexpected response status: ' + resp.statusText); + } + }) + .then(json => + this.setState({ + data: json.data, + loading: false, + }) + ) + .catch(error => { + this.setState({ + error, + loading: false + }) + }); + } + + handleExpressionChange(event) { + this.setState({expr: event.target.value}); + } + + render() { + return ( +
+ + {this.state.loading && "Loading..."} + {this.state.error} + +
); } } +class ExpressionInput extends Component { + constructor(props) { + super(props); + + this.handleKeyPress = this.handleKeyPress.bind(this); + } + + handleKeyPress(event) { + if (event.key === 'Enter' && !event.shiftKey) { + this.props.execute(); + event.preventDefault(); + } + } + + render() { + return ( +
+