aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiliano Ciavatta2020-07-08 11:21:13 +0000
committerEmiliano Ciavatta2020-07-08 11:21:13 +0000
commit7d05d0cea014b370601546a30f9e616d1efe5178 (patch)
tree50e3e1a6f14cbd0a4a9f65a78e1e2cf79ab09287
parentbcf5a985996c9988315bad5c3b745af4e48726c5 (diff)
Add connections display formats
-rw-r--r--frontend/src/colors.scss2
-rw-r--r--frontend/src/components/Connection.scss2
-rw-r--r--frontend/src/components/ConnectionContent.js85
-rw-r--r--frontend/src/components/ConnectionContent.scss5
-rw-r--r--frontend/src/index.scss10
-rw-r--r--frontend/src/views/App.js1
-rw-r--r--frontend/src/views/Connections.js16
-rw-r--r--frontend/src/views/Footer.scss3
-rw-r--r--frontend/src/views/MainPane.js27
9 files changed, 105 insertions, 46 deletions
diff --git a/frontend/src/colors.scss b/frontend/src/colors.scss
index ba0da55..064f9f5 100644
--- a/frontend/src/colors.scss
+++ b/frontend/src/colors.scss
@@ -16,4 +16,4 @@ $color-blue-dark: #013b4c;
$color-green: #25965d;
$color-green-light: #cde4d8;
-$color-green-dark: #004321; \ No newline at end of file
+$color-green-dark: #004321;
diff --git a/frontend/src/components/Connection.scss b/frontend/src/components/Connection.scss
index d3003bd..5ad195d 100644
--- a/frontend/src/components/Connection.scss
+++ b/frontend/src/components/Connection.scss
@@ -58,4 +58,4 @@
.arrow::after {
border-right-color: $color-primary-4;
}
-} \ No newline at end of file
+}
diff --git a/frontend/src/components/ConnectionContent.js b/frontend/src/components/ConnectionContent.js
index db63cbe..ece4bd6 100644
--- a/frontend/src/components/ConnectionContent.js
+++ b/frontend/src/components/ConnectionContent.js
@@ -1,37 +1,90 @@
import React, {Component} from 'react';
import './ConnectionContent.scss';
-import {Dropdown} from 'react-bootstrap';
+import {Col, Container, Dropdown, Row} from 'react-bootstrap';
+import axios from 'axios';
+import {withRouter} from "react-router-dom";
+import {Redirect} from "react-router";
class ConnectionContent extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ loading: false,
+ connectionContent: null,
+ format: "default"
+ };
+
+ this.validFormats = ["default", "hex", "hexdump", "base32", "base64", "ascii", "binary", "decimal", "octal"];
+ this.setFormat = this.setFormat.bind(this);
+ }
+
+ componentDidMount() {
+ if ('format' in this.props.match.params) {
+ this.setFormat(this.props.match.params.format);
+ }
+ }
+
+ componentDidUpdate(prevProps, prevState, snapshot) {
+ if (this.props.connection !== null && (
+ this.props.connection !== prevProps.connection || this.state.format !== prevState.format)) {
+ this.setState({loading: true});
+ axios.get(`/api/streams/${this.props.connection.id}?format=${this.state.format}`).then(res => {
+ this.setState({
+ connectionContent: res.data,
+ loading: false
+ });
+ });
+ }
+ }
+
+ setFormat(format) {
+ if (this.validFormats.includes(format)) {
+ this.setState({format: format});
+ }
+ }
+
render() {
- let content = this.props.connectionPayload;
+ let content = this.state.connectionContent;
- if (content === undefined) {
+ if (content === null) {
return <div>nope</div>;
}
- let payload = content.map(c =>
- <span key={c.id} className={c.from_client ? "from-client" : "from-server"} title="cccccc">
- {c.content}
+ const format = this.state.format !== "default" ? `/${this.state.format}` : "";
+ const redirect = <Redirect push to={`/connections/${this.props.connection.id}${format}`}/>;
+ let payload = content.map((c, i) =>
+ <span key={`content-${i}`} className={c.from_client ? "from-client" : "from-server"} title="cccccc">
+ {c.content}
</span>
);
return (
<div className="connection-content">
<div className="connection-content-options">
- <Dropdown>
- <Dropdown.Toggle variant="success" id="dropdown-basic">
+ <Container>
+ <Row>
+ <Col md={2}>ciao</Col>
+ </Row>
+ </Container>
+
+
+ <Dropdown onSelect={this.setFormat} >
+ <Dropdown.Toggle size="sm" id="dropdown-basic">
format
</Dropdown.Toggle>
<Dropdown.Menu>
- <Dropdown.Item href="#/action-1">plain</Dropdown.Item>
- <Dropdown.Item href="#/action-2">hex</Dropdown.Item>
- <Dropdown.Item href="#/action-3">hexdump</Dropdown.Item>
- <Dropdown.Item href="#/action-3">base32</Dropdown.Item>
- <Dropdown.Item href="#/action-3">base64</Dropdown.Item>
- <Dropdown.Item href="#/action-3">ascii</Dropdown.Item>
+ <Dropdown.Item eventKey="default" active={this.state.format === "default"}>plain</Dropdown.Item>
+ <Dropdown.Item eventKey="hex" active={this.state.format === "hex"}>hex</Dropdown.Item>
+ <Dropdown.Item eventKey="hexdump" active={this.state.format === "hexdump"}>hexdump</Dropdown.Item>
+ <Dropdown.Item eventKey="base32" active={this.state.format === "base32"}>base32</Dropdown.Item>
+ <Dropdown.Item eventKey="base64" active={this.state.format === "base64"}>base64</Dropdown.Item>
+ <Dropdown.Item eventKey="ascii" active={this.state.format === "ascii"}>ascii</Dropdown.Item>
+ <Dropdown.Item eventKey="binary" active={this.state.format === "binary"}>binary</Dropdown.Item>
+ <Dropdown.Item eventKey="decimal" active={this.state.format === "decimal"}>decimal</Dropdown.Item>
+ <Dropdown.Item eventKey="octal" active={this.state.format === "octal"}>octal</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
@@ -40,6 +93,8 @@ class ConnectionContent extends Component {
<pre>{payload}</pre>
+ {redirect}
+
</div>
);
@@ -48,4 +103,4 @@ class ConnectionContent extends Component {
}
-export default ConnectionContent;
+export default withRouter(ConnectionContent);
diff --git a/frontend/src/components/ConnectionContent.scss b/frontend/src/components/ConnectionContent.scss
index 61d9f63..a1b4afd 100644
--- a/frontend/src/components/ConnectionContent.scss
+++ b/frontend/src/components/ConnectionContent.scss
@@ -8,7 +8,10 @@
pre {
background-color: $color-primary-0;
padding: 10px 20px;
- word-break: break-all;
+ word-break: break-word;
+ max-width: 100%;
+ white-space: pre-wrap;
+ height: 100%;
}
.from-client {
diff --git a/frontend/src/index.scss b/frontend/src/index.scss
index c93d4b4..7db5cc5 100644
--- a/frontend/src/index.scss
+++ b/frontend/src/index.scss
@@ -4,7 +4,6 @@
@import 'colors.scss';
-
body {
margin: 0;
font-family: 'Fira Code', monospace;
@@ -12,7 +11,6 @@ body {
-moz-osx-font-smoothing: grayscale;
background-color: $color-primary-2;
color: $color-primary-4;
-
height: 100%;
max-height: 100%;
}
@@ -77,7 +75,8 @@ pre {
background-color: $color-green;
border-bottom: 5px solid $color-green-dark;
- &:hover, &:active {
+ &:hover,
+ &:active {
color: $color-green-light;
background-color: $color-green-dark;
}
@@ -133,7 +132,8 @@ textarea.form-control {
resize: none;
}
-input.form-control, textarea.form-control {
+input.form-control,
+textarea.form-control {
background-color: $color-primary-2;
border: none;
color: $color-primary-4;
@@ -164,4 +164,4 @@ input.form-control, textarea.form-control {
.text-muted {
color: $color-primary-4 !important;
-} \ No newline at end of file
+}
diff --git a/frontend/src/views/App.js b/frontend/src/views/App.js
index e3119aa..34e980e 100644
--- a/frontend/src/views/App.js
+++ b/frontend/src/views/App.js
@@ -26,6 +26,7 @@ class App extends Component {
<Router>
<Header onOpenServices={() => this.setState({servicesShow: true})}/>
<Switch>
+ <Route path="/connections/:id/:format" children={<MainPane/>}/>
<Route path="/connections/:id" children={<MainPane/>}/>
<Route path="/" children={<MainPane/>}/>
</Switch>
diff --git a/frontend/src/views/Connections.js b/frontend/src/views/Connections.js
index 1eeaede..5548c4c 100644
--- a/frontend/src/views/Connections.js
+++ b/frontend/src/views/Connections.js
@@ -4,6 +4,7 @@ import axios from 'axios'
import Connection from "../components/Connection";
import Table from 'react-bootstrap/Table';
import {Redirect} from 'react-router';
+import {withRouter} from "react-router-dom";
import {objectToQueryString} from "../utils";
class Connections extends Component {
@@ -24,12 +25,18 @@ class Connections extends Component {
this.queryLimit = 50;
this.handleScroll = this.handleScroll.bind(this);
+ this.connectionSelected = this.connectionSelected.bind(this);
}
componentDidMount() {
this.loadConnections({limit: this.queryLimit, hidden: this.state.showHidden});
}
+ connectionSelected(c) {
+ this.setState({selected: c.id});
+ this.props.onSelected(c);
+ }
+
handleScroll(e) {
let relativeScroll = e.currentTarget.scrollTop / (e.currentTarget.scrollHeight - e.currentTarget.clientHeight);
if (!this.state.loading && relativeScroll > this.scrollBottomThreashold) {
@@ -91,9 +98,10 @@ class Connections extends Component {
render() {
- let redirect = "";
+ let redirect = null;
if (this.state.selected) {
- redirect = <Redirect push to={"/connections/" + this.state.selected}/>;
+ const format = this.props.match.params.format;
+ redirect = <Redirect push to={`/connections/${this.state.selected}${format !== undefined ? ("/" + format) : ""}`} />;
}
let loading = null;
@@ -123,7 +131,7 @@ class Connections extends Component {
<tbody>
{
this.state.connections.map(c =>
- <Connection key={c.id} data={c} onSelected={() => this.setState({selected: c.id})}
+ <Connection key={c.id} data={c} onSelected={() => this.connectionSelected(c)}
selected={this.state.selected === c.id} onMarked={marked => c.marked = marked}
onEnabled={enabled => c.hidden = !enabled}/>
)
@@ -140,4 +148,4 @@ class Connections extends Component {
}
-export default Connections;
+export default withRouter(Connections);
diff --git a/frontend/src/views/Footer.scss b/frontend/src/views/Footer.scss
index c89f971..4119cfc 100644
--- a/frontend/src/views/Footer.scss
+++ b/frontend/src/views/Footer.scss
@@ -10,5 +10,4 @@
.footer-timeline {
height: 100px;
}
-
-} \ No newline at end of file
+}
diff --git a/frontend/src/views/MainPane.js b/frontend/src/views/MainPane.js
index e84f94c..69de725 100644
--- a/frontend/src/views/MainPane.js
+++ b/frontend/src/views/MainPane.js
@@ -3,32 +3,25 @@ import './MainPane.scss';
import Connections from "./Connections";
import ConnectionContent from "../components/ConnectionContent";
import {withRouter} from "react-router-dom";
-import axios from 'axios'
+import axios from 'axios';
class MainPane extends Component {
constructor(props) {
super(props);
this.state = {
- id: null,
+ selectedConnection: null
};
}
- componentDidUpdate() {
- if (this.props.match.params.id !== this.state.id) {
- const id = this.props.match.params.id;
- this.setState({id: id});
-
- axios.get(`/api/streams/${id}`).then(res => this.setState({connectionContent: res.data}));
- }
- }
-
componentDidMount() {
- if (this.props.match.params.id !== this.state.id) {
+ if ('id' in this.props.match.params) {
const id = this.props.match.params.id;
- this.setState({id: id});
-
- axios.get(`/api/streams/${id}`).then(res => this.setState({connectionContent: res.data}));
+ axios.get(`/api/connections/${id}`).then(res => {
+ if (res.status === 200) {
+ this.setState({selectedConnection: res.data});
+ }
+ });
}
}
@@ -38,10 +31,10 @@ class MainPane extends Component {
<div className="container-fluid">
<div className="row">
<div className="col-md-6 pane">
- <Connections/>
+ <Connections onSelected={(c) => this.setState({selectedConnection: c})} />
</div>
<div className="col-md-6 pl-0 pane">
- <ConnectionContent connectionPayload={this.state.connectionContent}/>
+ <ConnectionContent connection={this.state.selectedConnection}/>
</div>
</div>
</div>