aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/views
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/views')
-rw-r--r--frontend/src/views/App.js16
-rw-r--r--frontend/src/views/Connections.js19
-rw-r--r--frontend/src/views/Filters.js98
-rw-r--r--frontend/src/views/Filters.scss0
-rw-r--r--frontend/src/views/Header.js37
5 files changed, 145 insertions, 25 deletions
diff --git a/frontend/src/views/App.js b/frontend/src/views/App.js
index e3119aa..14ff7bf 100644
--- a/frontend/src/views/App.js
+++ b/frontend/src/views/App.js
@@ -5,26 +5,32 @@ import MainPane from "./MainPane";
import Footer from "./Footer";
import {BrowserRouter as Router, Route, Switch} from "react-router-dom";
import Services from "./Services";
+import Filters from "./Filters";
class App extends Component {
constructor(props) {
super(props);
this.state = {
- servicesShow: false
+ servicesWindowOpen: false,
+ filterWindowOpen: false
};
}
render() {
- let modal = "";
- if (this.state.servicesShow) {
- modal = <Services onHide={() => this.setState({servicesShow: false})}/>;
+ let modal;
+ if (this.state.servicesWindowOpen) {
+ modal = <Services onHide={() => this.setState({servicesWindowOpen: false})}/>;
+ }
+ if (this.state.filterWindowOpen) {
+ modal = <Filters onHide={() => this.setState({filterWindowOpen: false})}/>;
}
return (
<div className="app">
<Router>
- <Header onOpenServices={() => this.setState({servicesShow: true})}/>
+ <Header onOpenServices={() => this.setState({servicesWindowOpen: true})}
+ onOpenFilters={() => this.setState({filterWindowOpen: true})}/>
<Switch>
<Route path="/connections/:id" children={<MainPane/>}/>
<Route path="/" children={<MainPane/>}/>
diff --git a/frontend/src/views/Connections.js b/frontend/src/views/Connections.js
index 9b9fe35..62733d7 100644
--- a/frontend/src/views/Connections.js
+++ b/frontend/src/views/Connections.js
@@ -1,6 +1,6 @@
import React, {Component} from 'react';
import './Connections.scss';
-import axios from 'axios'
+import axios from 'axios';
import Connection from "../components/Connection";
import Table from 'react-bootstrap/Table';
import {Redirect} from 'react-router';
@@ -15,7 +15,6 @@ class Connections extends Component {
connections: [],
firstConnection: null,
lastConnection: null,
- showHidden: false,
prevParams: null,
flagRule: null,
rules: null,
@@ -33,7 +32,7 @@ class Connections extends Component {
}
componentDidMount() {
- this.loadConnections({limit: this.queryLimit, hidden: this.state.showHidden})
+ this.loadConnections({limit: this.queryLimit})
.then(() => this.setState({loaded: true}));
}
@@ -45,7 +44,7 @@ class Connections extends Component {
componentDidUpdate(prevProps, prevState, snapshot) {
if (this.state.loaded && prevProps.location.search !== this.props.location.search) {
this.setState({queryString: this.props.location.search});
- this.loadConnections({limit: this.queryLimit, hidden: this.state.showHidden})
+ this.loadConnections({limit: this.queryLimit})
.then(() => console.log("Connections reloaded after query string update"));
}
}
@@ -53,16 +52,12 @@ class Connections extends Component {
handleScroll(e) {
let relativeScroll = e.currentTarget.scrollTop / (e.currentTarget.scrollHeight - e.currentTarget.clientHeight);
if (!this.state.loading && relativeScroll > this.scrollBottomThreashold) {
- this.loadConnections({
- from: this.state.lastConnection.id, limit: this.queryLimit,
- hidden: this.state.showHidden
- }).then(() => console.log("Following connections loaded"));
+ this.loadConnections({from: this.state.lastConnection.id, limit: this.queryLimit,})
+ .then(() => console.log("Following connections loaded"));
}
if (!this.state.loading && relativeScroll < this.scrollTopThreashold) {
- this.loadConnections({
- to: this.state.firstConnection.id, limit: this.queryLimit,
- hidden: this.state.showHidden
- }).then(() => console.log("Previous connections loaded"));
+ this.loadConnections({to: this.state.firstConnection.id, limit: this.queryLimit,})
+ .then(() => console.log("Previous connections loaded"));
}
}
diff --git a/frontend/src/views/Filters.js b/frontend/src/views/Filters.js
new file mode 100644
index 0000000..23d3a00
--- /dev/null
+++ b/frontend/src/views/Filters.js
@@ -0,0 +1,98 @@
+import React, {Component} from 'react';
+import './Services.scss';
+import {Button, Col, Container, Modal, Row, Table} from "react-bootstrap";
+import {filtersDefinitions, filtersNames} from "../components/filters/FiltersDefinitions";
+
+class Filters extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {};
+ filtersNames.forEach(elem => this.state[`${elem}_active`] = false);
+ }
+
+ componentDidMount() {
+ let newState = {};
+ filtersNames.forEach(elem => newState[`${elem}_active`] = localStorage.getItem(`filters.${elem}`) === "true");
+ this.setState(newState);
+ }
+
+ checkboxChangesHandler(filterName, event) {
+ this.setState({[`${filterName}_active`]: event.target.checked});
+ localStorage.setItem(`filters.${filterName}`, event.target.checked);
+ if (typeof window !== "undefined") {
+ window.dispatchEvent(new Event("quick-filters"));
+ }
+ }
+
+ generateRows(filtersNames) {
+ return filtersNames.map(name =>
+ <tr>
+ <td><input type="checkbox"
+ checked={this.state[`${name}_active`]}
+ onChange={event => this.checkboxChangesHandler(name, event)} /></td>
+ <td>{filtersDefinitions[name]}</td>
+ </tr>
+ );
+ }
+
+ render() {
+ return (
+ <Modal
+ {...this.props}
+ show="true"
+ size="lg"
+ aria-labelledby="filters-dialog"
+ centered
+ >
+ <Modal.Header>
+ <Modal.Title id="filters-dialog">
+ ~/filters
+ </Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <Container>
+ <Row>
+ <Col md={6}>
+ <Table borderless size="sm" className="filters-table">
+ <thead>
+ <tr>
+ <th>show</th>
+ <th>filter</th>
+ </tr>
+ </thead>
+ <tbody>
+ {this.generateRows(["service_port", "client_address", "min_duration",
+ "min_bytes", "started_after", "closed_after", "marked"])}
+ </tbody>
+ </Table>
+ </Col>
+ <Col md={6}>
+ <Table borderless size="sm" className="filters-table">
+ <thead>
+ <tr>
+ <th>show</th>
+ <th>filter</th>
+ </tr>
+ </thead>
+ <tbody>
+ {this.generateRows(["matched_rules", "client_port", "max_duration",
+ "max_bytes", "started_before", "closed_before", "hidden"])}
+ </tbody>
+ </Table>
+ </Col>
+
+ </Row>
+
+
+ </Container>
+ </Modal.Body>
+ <Modal.Footer className="dialog-footer">
+ <Button variant="red" onClick={this.props.onHide}>close</Button>
+ </Modal.Footer>
+ </Modal>
+ );
+ }
+}
+
+export default Filters;
diff --git a/frontend/src/views/Filters.scss b/frontend/src/views/Filters.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/frontend/src/views/Filters.scss
diff --git a/frontend/src/views/Header.js b/frontend/src/views/Header.js
index 5118ec3..007be74 100644
--- a/frontend/src/views/Header.js
+++ b/frontend/src/views/Header.js
@@ -2,15 +2,18 @@ import React, {Component} from 'react';
import Typed from 'typed.js';
import './Header.scss';
import {Button} from "react-bootstrap";
-import ServicePortFilter from "../components/ServicePortFilter";
+import StringConnectionsFilter from "../components/filters/StringConnectionsFilter";
+import {cleanNumber, validateIpAddress, validateMin, validatePort} from "../utils";
+import RulesConnectionsFilter from "../components/filters/RulesConnectionsFilter";
+import {filtersDefinitions, filtersNames} from "../components/filters/FiltersDefinitions";
class Header extends Component {
constructor(props) {
super(props);
- this.state = {
- servicesShow: false
- };
+ this.state = {};
+ filtersNames.forEach(elem => this.state[`${elem}_active`] = false);
+ this.fetchStateFromLocalStorage = this.fetchStateFromLocalStorage.bind(this);
}
componentDidMount() {
@@ -20,13 +23,33 @@ class Header extends Component {
cursorChar: "❚"
};
this.typed = new Typed(this.el, options);
+
+ this.fetchStateFromLocalStorage();
+
+ if (typeof window !== "undefined") {
+ window.addEventListener("quick-filters", this.fetchStateFromLocalStorage);
+ }
}
componentWillUnmount() {
this.typed.destroy();
+
+ if (typeof window !== "undefined") {
+ window.removeEventListener("quick-filters", this.fetchStateFromLocalStorage);
+ }
+ }
+
+ fetchStateFromLocalStorage() {
+ let newState = {};
+ filtersNames.forEach(elem => newState[`${elem}_active`] = localStorage.getItem(`filters.${elem}`) === "true");
+ this.setState(newState);
}
render() {
+ let quickFilters = filtersNames.filter(name => this.state[`${name}_active`])
+ .map(name => filtersDefinitions[name])
+ .slice(0, 5);
+
return (
<header className="header container-fluid">
<div className="row">
@@ -41,16 +64,14 @@ class Header extends Component {
<div className="col-auto">
<div className="filters-bar-wrapper">
<div className="filters-bar">
- <ServicePortFilter />
- {/*<ServicePortFilter name="started_before" default="infinity" />*/}
- {/*<ServicePortFilter name="started_after" default="-infinity" />*/}
-
+ {quickFilters}
</div>
</div>
</div>
<div className="col">
<div className="header-buttons">
+ <Button onClick={this.props.onOpenFilters}>filters</Button>
<Button variant="yellow" size="sm">pcaps</Button>
<Button variant="blue">rules</Button>
<Button variant="red" onClick={this.props.onOpenServices}>