From 9dae0115592424929ffe4045069740365bc91d52 Mon Sep 17 00:00:00 2001 From: Emiliano Ciavatta Date: Sun, 9 Aug 2020 11:22:47 +0200 Subject: Update frontend filters --- frontend/src/views/App.js | 16 +++++-- frontend/src/views/Connections.js | 19 +++----- frontend/src/views/Filters.js | 98 +++++++++++++++++++++++++++++++++++++++ frontend/src/views/Filters.scss | 0 frontend/src/views/Header.js | 37 +++++++++++---- 5 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 frontend/src/views/Filters.js create mode 100644 frontend/src/views/Filters.scss (limited to 'frontend/src/views') 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 = this.setState({servicesShow: false})}/>; + let modal; + if (this.state.servicesWindowOpen) { + modal = this.setState({servicesWindowOpen: false})}/>; + } + if (this.state.filterWindowOpen) { + modal = this.setState({filterWindowOpen: false})}/>; } return (
-
this.setState({servicesShow: true})}/> +
this.setState({servicesWindowOpen: true})} + onOpenFilters={() => this.setState({filterWindowOpen: true})}/> }/> }/> 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 => + + this.checkboxChangesHandler(name, event)} /> + {filtersDefinitions[name]} + + ); + } + + render() { + return ( + + + + ~/filters + + + + + + + + + + + + + + + {this.generateRows(["service_port", "client_address", "min_duration", + "min_bytes", "started_after", "closed_after", "marked"])} + +
showfilter
+ + + + + + + + + + + {this.generateRows(["matched_rules", "client_port", "max_duration", + "max_bytes", "started_before", "closed_before", "hidden"])} + +
showfilter
+ + +
+ + +
+
+ + + +
+ ); + } +} + +export default Filters; diff --git a/frontend/src/views/Filters.scss b/frontend/src/views/Filters.scss new file mode 100644 index 0000000..e69de29 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 (
@@ -41,16 +64,14 @@ class Header extends Component {
- - {/**/} - {/**/} - + {quickFilters}
+