diff options
author | Emiliano Ciavatta | 2020-09-23 21:16:58 +0000 |
---|---|---|
committer | Emiliano Ciavatta | 2020-09-23 21:16:58 +0000 |
commit | 05678b74d98247c957faa1ca3d0bafc5f68974d1 (patch) | |
tree | 05a539466f0c91bced4d93bec2cb20e4325274b2 /frontend/src | |
parent | 04ee54be31931111bf89e50e4e54ac92b9a19d7a (diff) |
Add BooleanField
Diffstat (limited to 'frontend/src')
-rw-r--r-- | frontend/src/components/fields/BooleanField.js | 37 | ||||
-rw-r--r-- | frontend/src/components/fields/BooleanField.scss | 34 | ||||
-rw-r--r-- | frontend/src/components/fields/StringField.js | 16 | ||||
-rw-r--r-- | frontend/src/components/fields/StringField.scss | 2 | ||||
-rw-r--r-- | frontend/src/components/filters/BooleanConnectionsFilter.js | 12 | ||||
-rw-r--r-- | frontend/src/components/filters/BooleanConnectionsFilter.scss | 24 | ||||
-rw-r--r-- | frontend/src/components/filters/FiltersDefinitions.js | 34 | ||||
-rw-r--r-- | frontend/src/components/filters/StringConnectionsFilter.js | 31 | ||||
-rw-r--r-- | frontend/src/components/filters/StringConnectionsFilter.scss | 66 | ||||
-rw-r--r-- | frontend/src/components/panels/PcapPane.js | 4 | ||||
-rw-r--r-- | frontend/src/index.scss | 27 | ||||
-rw-r--r-- | frontend/src/utils.js | 4 | ||||
-rw-r--r-- | frontend/src/views/Header.js | 6 | ||||
-rw-r--r-- | frontend/src/views/Header.scss | 8 | ||||
-rw-r--r-- | frontend/src/views/MainPane.js | 4 |
15 files changed, 131 insertions, 178 deletions
diff --git a/frontend/src/components/fields/BooleanField.js b/frontend/src/components/fields/BooleanField.js new file mode 100644 index 0000000..06a6da7 --- /dev/null +++ b/frontend/src/components/fields/BooleanField.js @@ -0,0 +1,37 @@ +import React, {Component} from 'react'; +import './BooleanField.scss'; +import {randomClassName} from "../../utils"; + +const classNames = require('classnames'); + +class BooleanField extends Component { + + constructor(props) { + super(props); + + this.id = `field-${this.props.name || "noname"}-${randomClassName()}`; + } + + render() { + + const checked = this.props.checked || false; + const small = this.props.small || false; + const name = this.props.name || null; + const handler = () => { + if (this.props.onChange) { + this.props.onChange(!checked); + } + }; + + return ( + <div className={classNames( "boolean-field", {"field-checked" : checked}, {"field-small": small})}> + <div className="field-input"> + <input type="checkbox" id={this.id} checked={checked} onChange={handler} /> + <label htmlFor={this.id}>{(checked ? "✓ " : "✗ ") + name}</label> + </div> + </div> + ); + } +} + +export default BooleanField; diff --git a/frontend/src/components/fields/BooleanField.scss b/frontend/src/components/fields/BooleanField.scss new file mode 100644 index 0000000..6ec25f7 --- /dev/null +++ b/frontend/src/components/fields/BooleanField.scss @@ -0,0 +1,34 @@ +@import '../../colors.scss'; + +.boolean-field { + font-size: 0.9em; + + .field-input { + border-radius: 5px; + width: fit-content; + background-color: $color-primary-2; + + input { + display: none; + } + + label { + margin: 0; + padding: 6px 15px; + cursor: pointer; + } + + &:hover { + background-color: $color-primary-1; + } + } + + &.field-checked .field-input { + background-color: $color-primary-4 !important; + color: $color-primary-3; + } + + &.field-small { + font-size: 0.8em; + } +} diff --git a/frontend/src/components/fields/StringField.js b/frontend/src/components/fields/StringField.js index aa23fe8..7781b2d 100644 --- a/frontend/src/components/fields/StringField.js +++ b/frontend/src/components/fields/StringField.js @@ -6,8 +6,14 @@ const classNames = require('classnames'); class StringField extends Component { + constructor(props) { + super(props); + + this.id = `field-${this.props.name || "noname"}-${randomClassName()}`; + } + render() { - const id = `field-${this.props.name || "noname"}-${randomClassName()}`; + const active = this.props.active || false; const invalid = this.props.invalid || false; const small = this.props.small || false; @@ -27,18 +33,18 @@ class StringField extends Component { }; return ( - <div className={classNames("field", "string-field", {"field-active" : active}, - {"field-invalid": invalid}, {"field-small": small}, {"field-inline": inline})}> + <div className={classNames("string-field", {"field-active" : active}, {"field-invalid": invalid}, + {"field-small": small}, {"field-inline": inline})}> <div className="field-wrapper"> { name && <div className="field-name"> - <label id={id}>{name}:</label> + <label id={this.id}>{name}:</label> </div> } <div className="field-input"> <div className="field-value"> <input type={type} placeholder={this.props.defaultValue} aria-label={name} - aria-describedby={id} onChange={handler} value={value} /> + aria-describedby={this.id} onChange={handler} value={value} /> </div> { value !== "" && <div className="field-clear"> diff --git a/frontend/src/components/fields/StringField.scss b/frontend/src/components/fields/StringField.scss index 674815f..2523c8d 100644 --- a/frontend/src/components/fields/StringField.scss +++ b/frontend/src/components/fields/StringField.scss @@ -1,6 +1,6 @@ @import '../../colors.scss'; -.field { +.string-field { font-size: 0.9em; .field-name { diff --git a/frontend/src/components/filters/BooleanConnectionsFilter.js b/frontend/src/components/filters/BooleanConnectionsFilter.js index 7dea7cf..490d185 100644 --- a/frontend/src/components/filters/BooleanConnectionsFilter.js +++ b/frontend/src/components/filters/BooleanConnectionsFilter.js @@ -1,9 +1,7 @@ import React, {Component} from 'react'; import {withRouter} from "react-router-dom"; import {Redirect} from "react-router"; -import './BooleanConnectionsFilter.scss'; - -const classNames = require('classnames'); +import BooleanField from "../fields/BooleanField"; class BooleanConnectionsFilter extends Component { @@ -57,11 +55,9 @@ class BooleanConnectionsFilter extends Component { } return ( - <div className={classNames("filter", "d-inline-block", {"filter-active" : this.toBoolean(this.state.filterActive)})}> - <div className="filter-boolean" onClick={this.filterChanged}> - <span>{this.props.filterName}</span> - </div> - + <div className="filter" style={{"width": `${this.props.width}px`}}> + <BooleanField checked={this.toBoolean(this.state.filterActive)} name={this.props.filterName} + onChange={this.filterChanged} /> {redirect} </div> ); diff --git a/frontend/src/components/filters/BooleanConnectionsFilter.scss b/frontend/src/components/filters/BooleanConnectionsFilter.scss deleted file mode 100644 index 941b967..0000000 --- a/frontend/src/components/filters/BooleanConnectionsFilter.scss +++ /dev/null @@ -1,24 +0,0 @@ -@import '../../colors'; - -.filter { - .filter-boolean { - padding: 0 10px; - background-color: $color-primary-2; - border-radius: 5px; - cursor: pointer; - height: 34px; - - span { - display: block; - font-size: 13px; - padding: 6px 5px; - } - } - - &.filter-active { - .filter-boolean { - background-color: $color-primary-4; - color: $color-primary-3; - } - } -} diff --git a/frontend/src/components/filters/FiltersDefinitions.js b/frontend/src/components/filters/FiltersDefinitions.js index d36792e..02ccb42 100644 --- a/frontend/src/components/filters/FiltersDefinitions.js +++ b/frontend/src/components/filters/FiltersDefinitions.js @@ -12,7 +12,6 @@ import React from "react"; import RulesConnectionsFilter from "./RulesConnectionsFilter"; import BooleanConnectionsFilter from "./BooleanConnectionsFilter"; - export const filtersNames = ["service_port", "matched_rules", "client_address", "client_port", "min_duration", "max_duration", "min_bytes", "max_bytes", "started_after", "started_before", "closed_after", "closed_before", "marked", "hidden"]; @@ -22,59 +21,70 @@ export const filtersDefinitions = { defaultFilterValue="all_ports" replaceFunc={cleanNumber} validateFunc={validatePort} - key="service_port_filter" />, + key="service_port_filter" + width={200} />, matched_rules: <RulesConnectionsFilter />, client_address: <StringConnectionsFilter filterName="client_address" defaultFilterValue="all_addresses" validateFunc={validateIpAddress} - key="client_address_filter" />, + key="client_address_filter" + width={320} />, client_port: <StringConnectionsFilter filterName="client_port" defaultFilterValue="all_ports" replaceFunc={cleanNumber} validateFunc={validatePort} - key="client_port_filter" />, + key="client_port_filter" + width={200} />, min_duration: <StringConnectionsFilter filterName="min_duration" defaultFilterValue="0" replaceFunc={cleanNumber} validateFunc={validateMin(0)} - key="min_duration_filter" />, + key="min_duration_filter" + width={200} />, max_duration: <StringConnectionsFilter filterName="max_duration" defaultFilterValue="∞" replaceFunc={cleanNumber} - key="max_duration_filter" />, + key="max_duration_filter" + width={200} />, min_bytes: <StringConnectionsFilter filterName="min_bytes" defaultFilterValue="0" replaceFunc={cleanNumber} validateFunc={validateMin(0)} - key="min_bytes_filter" />, + key="min_bytes_filter" + width={200} />, max_bytes: <StringConnectionsFilter filterName="max_bytes" defaultFilterValue="∞" replaceFunc={cleanNumber} - key="max_bytes_filter" />, + key="max_bytes_filter" + width={200} />, started_after: <StringConnectionsFilter filterName="started_after" defaultFilterValue="00:00:00" validateFunc={validate24HourTime} encodeFunc={timeToTimestamp} decodeFunc={timestampToTime} - key="started_after_filter" />, + key="started_after_filter" + width={200} />, started_before: <StringConnectionsFilter filterName="started_before" defaultFilterValue="00:00:00" validateFunc={validate24HourTime} encodeFunc={timeToTimestamp} decodeFunc={timestampToTime} - key="started_before_filter" />, + key="started_before_filter" + width={200} />, closed_after: <StringConnectionsFilter filterName="closed_after" defaultFilterValue="00:00:00" validateFunc={validate24HourTime} encodeFunc={timeToTimestamp} decodeFunc={timestampToTime} - key="closed_after_filter" />, + key="closed_after_filter" + width={200} />, closed_before: <StringConnectionsFilter filterName="closed_before" defaultFilterValue="00:00:00" validateFunc={validate24HourTime} encodeFunc={timeToTimestamp} decodeFunc={timestampToTime} - key="closed_before_filter" />, + key="closed_before_filter" + width={200} />, marked: <BooleanConnectionsFilter filterName={"marked"} />, hidden: <BooleanConnectionsFilter filterName={"hidden"} /> }; diff --git a/frontend/src/components/filters/StringConnectionsFilter.js b/frontend/src/components/filters/StringConnectionsFilter.js index 490a569..0d7f063 100644 --- a/frontend/src/components/filters/StringConnectionsFilter.js +++ b/frontend/src/components/filters/StringConnectionsFilter.js @@ -1,9 +1,7 @@ import React, {Component} from 'react'; import {withRouter} from "react-router-dom"; import {Redirect} from "react-router"; -import './StringConnectionsFilter.scss'; - -const classNames = require('classnames'); +import StringField from "../fields/StringField"; class StringConnectionsFilter extends Component { @@ -62,8 +60,7 @@ class StringConnectionsFilter extends Component { (typeof this.props.validateFunc === "function" && this.props.validateFunc(value)); } - filterChanged(event) { - let fieldValue = event.target.value; + filterChanged(fieldValue) { if (this.state.timeoutHandle !== null) { clearTimeout(this.state.timeoutHandle); } @@ -116,26 +113,10 @@ class StringConnectionsFilter extends Component { let active = this.state.filterValue !== null; return ( - <div className={classNames("filter", "d-inline-block", {"filter-active" : active}, - {"filter-invalid": this.state.invalidValue})} style={{"width": "200px"}}> - <div className="input-group"> - <div className="filter-name-wrapper"> - <span className="filter-name" id={`filter-${this.props.filterName}`}>{this.props.filterName}:</span> - </div> - <input placeholder={this.props.defaultFilterValue} aria-label={this.props.filterName} - aria-describedby={`filter-${this.props.filterName}`} className="form-control filter-value" - onChange={this.filterChanged} value={this.state.fieldValue} /> - </div> - - { active && - <div className="filter-delete"> - <span className="filter-delete-icon" onClick={() => { - this.needRedirect = true; - this.setState({fieldValue: "", filterValue: null}); - }}>del</span> - </div> - } - + <div className="filter" style={{"width": `${this.props.width}px`}}> + <StringField active={active} invalid={this.state.invalidValue} name={this.props.filterName} + defaultValue={this.props.defaultFilterValue} onChange={this.filterChanged} + value={this.state.fieldValue} inline={true} small={true} /> {redirect} </div> ); diff --git a/frontend/src/components/filters/StringConnectionsFilter.scss b/frontend/src/components/filters/StringConnectionsFilter.scss deleted file mode 100644 index 1476616..0000000 --- a/frontend/src/components/filters/StringConnectionsFilter.scss +++ /dev/null @@ -1,66 +0,0 @@ -@import '../../colors'; - -.filter { - margin: 0 10px; - position: relative; - - .filter-name-wrapper { - background-color: $color-primary-2; - padding: 3px 7px; - border-top-left-radius: 5px; - border-bottom-left-radius: 5px; - } - - .filter-name { - font-size: 13px; - } - - .filter-value { - font-size: 13px; - padding-left: 0; - border-radius: 5px; - - &:focus { - background-color: $color-primary-2; - } - } - - &.filter-active { - .filter-name-wrapper { - background-color: $color-primary-4; - color: $color-primary-3; - } - - .filter-value { - background-color: $color-primary-4; - color: $color-primary-3; - } - } - - &.filter-invalid { - .filter-name-wrapper { - background-color: $color-secondary-2; - color: $color-primary-4; - } - - .filter-value { - background-color: $color-secondary-2; - color: $color-primary-4; - } - } - - .filter-delete { - position: absolute; - right: 10px; - top: 10px; - z-index: 10; - font-size: 11px; - letter-spacing: -0.5px; - color: $color-primary-2; - cursor: pointer; - - .filter-delete-icon { - font-weight: 800; - } - } -} diff --git a/frontend/src/components/panels/PcapPane.js b/frontend/src/components/panels/PcapPane.js index 817c7b5..9f3bc19 100644 --- a/frontend/src/components/panels/PcapPane.js +++ b/frontend/src/components/panels/PcapPane.js @@ -5,6 +5,7 @@ import backend from "../../backend"; import {formatSize, timestampToTime2} from "../../utils"; import {Container, Row, Col, Form} from "react-bootstrap"; import StringField from "../fields/StringField"; +import BooleanField from "../fields/BooleanField"; class PcapPane extends Component { @@ -13,6 +14,7 @@ class PcapPane extends Component { this.state = { sessions: [], + test: false }; this.loadSessions = this.loadSessions.bind(this); @@ -86,7 +88,7 @@ class PcapPane extends Component { <br/><br/><br/><br/> - <StringField /> + <BooleanField small={true} name={"marked"} checked={this.state.test} onChange={(v) => this.setState({test: v})} /> </div> </Col> diff --git a/frontend/src/index.scss b/frontend/src/index.scss index 358fd70..5d1bbfa 100644 --- a/frontend/src/index.scss +++ b/frontend/src/index.scss @@ -13,6 +13,7 @@ body { color: $color-primary-4; height: 100%; max-height: 100%; + font-size: 100%; } pre { @@ -182,32 +183,6 @@ textarea.form-control { resize: none; } -input.form-control, -textarea.form-control { - background-color: $color-primary-2; - border: none; - color: $color-primary-4; - font-family: 'Fira Code', monospace; - - &:focus { - background-color: $color-primary-1; - color: $color-primary-4; - box-shadow: none; - } - - &[readonly] { - background-color: $color-primary-2; - border: none; - color: $color-primary-4; - } - - &[readonly]:focus { - background-color: $color-primary-1; - color: $color-primary-4; - box-shadow: none; - } -} - .table { color: $color-primary-4; } diff --git a/frontend/src/utils.js b/frontend/src/utils.js index c81cdfc..46667d6 100644 --- a/frontend/src/utils.js +++ b/frontend/src/utils.js @@ -83,6 +83,6 @@ export function formatSize(size) { } } -export function randomClassName(size = 10) { - return Math.random().toString(36).substring(size); +export function randomClassName() { + return Math.random().toString(36).slice(2) } diff --git a/frontend/src/views/Header.js b/frontend/src/views/Header.js index 5860d80..deb3ab7 100644 --- a/frontend/src/views/Header.js +++ b/frontend/src/views/Header.js @@ -60,10 +60,8 @@ class Header extends Component { </div> <div className="col-auto"> - <div className="filters-bar-wrapper"> - <div className="filters-bar"> - {quickFilters} - </div> + <div className="filters-bar"> + {quickFilters} </div> </div> diff --git a/frontend/src/views/Header.scss b/frontend/src/views/Header.scss index e36b2d6..f3bfec1 100644 --- a/frontend/src/views/Header.scss +++ b/frontend/src/views/Header.scss @@ -22,8 +22,12 @@ } } - .filters-bar-wrapper { - height: 50px; + .filters-bar { padding: 8px 0; + + .filter { + display: inline-block; + margin-right: 10px; + } } } diff --git a/frontend/src/views/MainPane.js b/frontend/src/views/MainPane.js index 3c0d795..88af4a7 100644 --- a/frontend/src/views/MainPane.js +++ b/frontend/src/views/MainPane.js @@ -35,8 +35,8 @@ class MainPane extends Component { <Connections onSelected={(c) => this.setState({selectedConnection: c})} /> </div> <div className="col-md-6 pl-0 pane"> - {/*<PcapPane />*/} - <ConnectionContent connection={this.state.selectedConnection}/> + <PcapPane /> + {/*<ConnectionContent connection={this.state.selectedConnection}/>*/} </div> </div> </div> |