aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/views
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/views')
-rw-r--r--frontend/src/views/App.js19
-rw-r--r--frontend/src/views/Connections.js61
-rw-r--r--frontend/src/views/Connections.scss32
-rw-r--r--frontend/src/views/Header.js22
-rw-r--r--frontend/src/views/MainPane.js10
-rw-r--r--frontend/src/views/Services.js142
-rw-r--r--frontend/src/views/Services.scss16
7 files changed, 242 insertions, 60 deletions
diff --git a/frontend/src/views/App.js b/frontend/src/views/App.js
index 4d80da5..2b444a2 100644
--- a/frontend/src/views/App.js
+++ b/frontend/src/views/App.js
@@ -4,20 +4,35 @@ import './App.scss';
import MainPane from "./MainPane";
import Footer from "./Footer";
import {Route, BrowserRouter as Router, Switch} from "react-router-dom";
+import Services from "./Services";
class App extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ servicesShow: false
+ };
+ }
+
render() {
+ let modal = ""
+ if (this.state.servicesShow) {
+ modal = <Services onHide={() => this.setState({servicesShow: false})} />
+ }
+
return (
<div className="app">
<Router>
- <Header/>
+ <Header onOpenServices={() => this.setState({servicesShow: true})}/>
<Switch>
+ <Route path="/connections/:id" children={<MainPane/>} />
<Route path="/" children={<MainPane/>} />
- <Route path="/connection/:id" children={<MainPane/>} />
</Switch>
+ {modal}
<Footer/>
</Router>
+
</div>
);
}
diff --git a/frontend/src/views/Connections.js b/frontend/src/views/Connections.js
index 5876a40..fa7798e 100644
--- a/frontend/src/views/Connections.js
+++ b/frontend/src/views/Connections.js
@@ -2,8 +2,8 @@ import React, {Component} from 'react';
import './Connections.scss';
import axios from 'axios'
import Connection from "../components/Connection";
-import {Link} from "react-router-dom";
import Table from 'react-bootstrap/Table';
+import {Redirect} from 'react-router';
class Connections extends Component {
constructor(props) {
@@ -19,34 +19,16 @@ class Connections extends Component {
}
render() {
- let connection = {
- "id": "5dd95ff0fe7ae01ae7f419c2",
- "ip_src": "10.62.82.1",
- "ip_dst": "10.62.82.2",
- "port_src": 59113,
- "port_dst": 23179,
- "started_at": "2019-11-23T16:36:00.1Z",
- "closed_at": "2019-11-23T16:36:00.971Z",
- "client_bytes": 331,
- "server_bytes": 85,
- "client_documents": 1,
- "server_documents": 1,
- "processed_at": "2020-04-21T17:10:29.532Z",
- "matched_rules": [],
- "hidden": false,
- "marked": true,
- "comment": "",
- "service": {
- "port": 23179,
- "name": "kaboom",
- "color": "#3C6D3C",
- "notes": "wdddoddddddw"
- }
+ let redirect = ""
+ if (this.state.selected) {
+ redirect = <Redirect push to={"/connections/" + this.state.selected} />;
}
return (
+
<div className="connections">
- <Table striped hover>
+ <div className="connections-header-padding"/>
+ <Table borderless size="sm">
<thead>
<tr>
<th>service</th>
@@ -61,31 +43,16 @@ class Connections extends Component {
</tr>
</thead>
<tbody>
- <tr>
- <td>1</td>
- <td>Mark</td>
- <td>Otto</td>
- <td>@mdo</td>
- </tr>
- <tr>
- <td>2</td>
- <td>Jacob</td>
- <td>Thornton</td>
- <td>@fat</td>
- </tr>
- <tr>
- <td>3</td>
- <td colSpan="2">Larry the Bird</td>
- <td>@twitter</td>
- </tr>
+ {
+ this.state.connections.map(c =>
+ <Connection key={c.id} data={c} onSelected={() => this.setState({selected: c.id})}
+ selected={this.state.selected === c.id}/>
+ )
+ }
</tbody>
</Table>
- {
- this.state.connections.map(c =>
- <Link to={"/connection/" + c.id}><Connection data={c} /></Link>
- )
- }
+ {redirect}
</div>
);
}
diff --git a/frontend/src/views/Connections.scss b/frontend/src/views/Connections.scss
index da74e11..6d2de3f 100644
--- a/frontend/src/views/Connections.scss
+++ b/frontend/src/views/Connections.scss
@@ -2,12 +2,40 @@
.connections {
background-color: $color-primary-3;
- padding: 10px 10px 10px 10px;
+ padding: 0 10px;
+ position: relative;
height: 100%;
overflow: auto;
.table {
- color: $color-primary-4;
+ margin-top: 10px;
}
+
+ .connections-header-padding {
+ position: sticky;
+ height: 10px;
+ background-color: $color-primary-3;
+ top: 0;
+ left: 0;
+ right: 0;
+ margin-bottom: -10px;
+ }
+
+ th {
+ background-color: $color-primary-2;
+ border-top: 3px solid $color-primary-3;
+ border-bottom: 3px solid $color-primary-3;
+ font-size: 13.5px;
+
+ position: sticky;
+ top: 10px;
+ padding: 5px;
+ }
+
+ &:hover::-webkit-scrollbar-thumb {
+ background: $color-secondary-2;
+ }
+
+
} \ No newline at end of file
diff --git a/frontend/src/views/Header.js b/frontend/src/views/Header.js
index b3f919b..ac272e6 100644
--- a/frontend/src/views/Header.js
+++ b/frontend/src/views/Header.js
@@ -1,9 +1,17 @@
import React, {Component} from 'react';
import Typed from 'typed.js';
import './Header.scss';
+import {Button} from "react-bootstrap";
class Header extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ servicesShow: false
+ };
+ }
+
componentDidMount() {
const options = {
strings: ["caronte$ "],
@@ -28,15 +36,11 @@ class Header extends Component {
</div>
<div className="col">
<div className="header-buttons">
- <button className="btn-primary">
- ➕ pcaps
- </button>
- <button className="btn-primary">
- ➕ rules
- </button>
- <button className="btn-primary">
- ➕ services
- </button>
+ <Button variant="yellow" size="sm">pcaps</Button>
+ <Button variant="blue">rules</Button>
+ <Button variant="red" onClick={this.props.onOpenServices}>
+ services
+ </Button>
</div>
</div>
</div>
diff --git a/frontend/src/views/MainPane.js b/frontend/src/views/MainPane.js
index 88b5376..0fc083e 100644
--- a/frontend/src/views/MainPane.js
+++ b/frontend/src/views/MainPane.js
@@ -26,6 +26,16 @@ class MainPane extends Component {
}
componentDidMount() {
+ 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}))
+
+
+ }
+
+
}
render() {
diff --git a/frontend/src/views/Services.js b/frontend/src/views/Services.js
new file mode 100644
index 0000000..1b3789d
--- /dev/null
+++ b/frontend/src/views/Services.js
@@ -0,0 +1,142 @@
+import React, {Component} from 'react';
+import './Services.scss';
+import {Button, ButtonGroup, Col, Container, Form, FormControl, InputGroup, Modal, Row, Table} from "react-bootstrap";
+import axios from 'axios'
+import {createCurlCommand} from '../utils';
+
+class Services extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ services: {},
+ port: "",
+ portValid: false
+ }
+
+ this.portChanged = this.portChanged.bind(this);
+ }
+
+ componentDidMount() {
+ axios.get("/api/services").then(res => this.setState({services: res.data}))
+ }
+
+ portChanged(event) {
+ let value = event.target.value.replace(/[^\d]/gi, '')
+ let intValue = parseInt(value)
+ this.setState({port: value, portValid: intValue > 0 && intValue <= 65565})
+
+
+ }
+
+
+ render() {
+ let curl = createCurlCommand("/services", {
+ "port": this.state.port,
+ "name": "aaaaa",
+ "color": "#fff",
+ "notes": "aaa"
+ })
+
+ let rows = Object.values(this.state.services).map(s =>
+ <tr>
+ <td><Button size="sm" style={{
+ "backgroundColor": s.color
+ }}>edit</Button></td>
+ <td>{s.port}</td>
+ <td>{s.name}</td>
+ </tr>
+ )
+
+
+
+
+ return (
+ <Modal
+ {...this.props}
+ show="true"
+ size="lg"
+ aria-labelledby="contained-modal-title-vcenter"
+ centered
+ >
+ <Modal.Header>
+ <Modal.Title id="contained-modal-title-vcenter">
+ ~/services
+ </Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <Container>
+ <Row>
+ <Col md={7}>
+ <Table borderless size="sm" className="services-list">
+ <thead>
+ <tr>
+ <th><Button size="sm">new</Button></th>
+ <th>name</th>
+ <th>port</th>
+ </tr>
+ </thead>
+ <tbody>
+ {rows}
+ </tbody>
+ </Table>
+ </Col>
+ <Col md={5}>
+ <Form>
+ <Form.Group controlId="servicePort">
+ <Form.Label>port:</Form.Label>
+ <Form.Control type="text" onChange={this.portChanged} value={this.state.port} />
+ <Form.Text className="text-muted">
+ {!this.state.portValid ? "assert(1 <= port <= 65565)" : ""}
+ </Form.Text>
+ </Form.Group>
+
+ <Form.Group controlId="serviceName">
+ <Form.Label>name:</Form.Label>
+ <Form.Control type="text" required min={3} max={16} />
+ <Form.Text className="text-muted">
+ {"assert(len(name) >= 3)"}
+ </Form.Text>
+ </Form.Group>
+
+ <Form.Group controlId="serviceColor">
+ <Form.Label>color:</Form.Label>
+ <ButtonGroup aria-label="Basic example">
+ <Button variant="secondary">Left</Button>
+ <Button variant="secondary">Middle</Button>
+ <Button variant="secondary">Right</Button>
+ </ButtonGroup>
+ </Form.Group>
+
+ <Form.Group controlId="serviceNotes">
+ <Form.Label>notes:</Form.Label>
+ <Form.Control type="textarea" />
+ </Form.Group>
+ </Form>
+
+
+ </Col>
+
+ </Row>
+
+ <Row>
+ <Col md={12}>
+ <InputGroup>
+ <FormControl as="textarea" rows={9} className="curl-output" readOnly={true}>{curl}
+ </FormControl>
+ </InputGroup>
+
+ </Col>
+ </Row>
+ </Container>
+ </Modal.Body>
+ <Modal.Footer className="dialog-footer">
+ <Button variant="green" onClick={this.props.onHide}>save</Button>
+ <Button variant="red" onClick={this.props.onHide}>close</Button>
+ </Modal.Footer>
+ </Modal>
+ );
+ }
+}
+
+export default Services;
diff --git a/frontend/src/views/Services.scss b/frontend/src/views/Services.scss
new file mode 100644
index 0000000..fd65beb
--- /dev/null
+++ b/frontend/src/views/Services.scss
@@ -0,0 +1,16 @@
+.curl-output {
+ width: 100%;
+ font-size: 13px;
+}
+
+.services-list {
+ .btn {
+ width: 150px;
+ }
+}
+
+.dialog-footer {
+ .btn {
+ width: 80px;
+ }
+} \ No newline at end of file