diff options
author | Emiliano Ciavatta | 2020-10-19 10:40:53 +0000 |
---|---|---|
committer | Emiliano Ciavatta | 2020-10-19 10:40:53 +0000 |
commit | 18287f888b0c3ae80422d4068c511614b55bfa6d (patch) | |
tree | 1afb5eab88efeee79a6b4a37aef1ce0061af89b5 /frontend | |
parent | 3a96b841f06bb1049b0625c6d20e8f8f46c8f2ab (diff) |
Add resizable layout
Diffstat (limited to 'frontend')
-rw-r--r-- | frontend/package.json | 1 | ||||
-rw-r--r-- | frontend/src/components/Header.js | 28 | ||||
-rw-r--r-- | frontend/src/components/Header.scss | 17 | ||||
-rw-r--r-- | frontend/src/components/Timeline.js | 2 | ||||
-rw-r--r-- | frontend/src/components/pages/ConfigurationPage.scss | 9 | ||||
-rw-r--r-- | frontend/src/components/pages/MainPage.js | 69 | ||||
-rw-r--r-- | frontend/src/components/pages/MainPage.scss | 22 | ||||
-rw-r--r-- | frontend/src/components/pages/common.scss | 15 | ||||
-rw-r--r-- | frontend/src/components/panels/StreamsPane.scss | 6 | ||||
-rw-r--r-- | frontend/src/index.scss | 30 | ||||
-rw-r--r-- | frontend/yarn.lock | 44 |
11 files changed, 162 insertions, 81 deletions
diff --git a/frontend/package.json b/frontend/package.json index b3ad03a..c91665f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,6 +23,7 @@ "react-dom": "^16.13.1", "react-input-mask": "^3.0.0-alpha.2", "react-json-view": "^1.19.1", + "react-reflex": "^3.1.0", "react-router": "^5.1.2", "react-router-dom": "^5.1.2", "react-scripts": "3.4.1", diff --git a/frontend/src/components/Header.js b/frontend/src/components/Header.js index c46d768..4db05a5 100644 --- a/frontend/src/components/Header.js +++ b/frontend/src/components/Header.js @@ -46,19 +46,17 @@ class Header extends Component { render() { return ( - <header className="header container-fluid"> - <div className="row"> - <div className={classNames({"col-auto": this.props.configured, "col": !this.props.configured})}> - <h1 className="header-title type-wrap"> - <Link to="/"> - <span style={{whiteSpace: "pre"}} ref={(el) => { - this.el = el; - }}/> - </Link> - </h1> - </div> + <header className={classNames("header", {"configured": this.props.configured})}> + <div className="header-content"> + <h1 className="header-title type-wrap"> + <Link to="/"> + <span style={{whiteSpace: "pre"}} ref={(el) => { + this.el = el; + }}/> + </Link> + </h1> - {this.props.configured && <div className="col-auto"> + {this.props.configured && <div className="filters-bar"> <StringConnectionsFilter filterName="service_port" defaultFilterValue="all_ports" @@ -71,9 +69,9 @@ class Header extends Component { <ExitSearchFilter/> <AdvancedFilters onClick={this.props.onOpenFilters}/> </div> - </div>} + } - {this.props.configured && <div className="col"> + {this.props.configured && <div className="header-buttons"> <Link to={"/searches" + this.props.location.search}> <ButtonField variant="pink" name="searches" bordered/> @@ -91,7 +89,7 @@ class Header extends Component { <ButtonField variant="blue" name="config" bordered/> </Link> </div> - </div>} + } </div> </header> ); diff --git a/frontend/src/components/Header.scss b/frontend/src/components/Header.scss index fff28e6..c6a88b7 100644 --- a/frontend/src/components/Header.scss +++ b/frontend/src/components/Header.scss @@ -1,16 +1,18 @@ @import "../colors"; .header { - height: 80px; - padding: 15px 30px; + padding: 15px; - > .row { + .header-content { + display: flex; + width: 100%; + padding: 0 10px; background-color: $color-primary-0; } .header-title { width: 200px; - margin: 5px 0 5px -5px; + margin: 5px 0 5px 0; } .header-buttons { @@ -24,6 +26,7 @@ } .filters-bar { + flex: 1; padding: 3px 0; .filter, @@ -38,4 +41,10 @@ border-radius: 5px; } } + + @media screen and (max-width: 1530px) { + &.configured .header-title { + display: none; + } + } } diff --git a/frontend/src/components/Timeline.js b/frontend/src/components/Timeline.js index 9ecbd80..5443a3b 100644 --- a/frontend/src/components/Timeline.js +++ b/frontend/src/components/Timeline.js @@ -256,7 +256,7 @@ class Timeline extends Component { enablePanZoom={true} utc={false} onTimeRangeChanged={this.handleTimeRangeChange}> - <ChartRow height="125"> + <ChartRow height={this.props.height - 70}> <YAxis id="axis1" hideAxisLine min={this.aggregateSeries("min")} max={this.aggregateSeries("max")} width="35" type="linear" transition={300}/> diff --git a/frontend/src/components/pages/ConfigurationPage.scss b/frontend/src/components/pages/ConfigurationPage.scss index 4254547..2ceccd5 100644 --- a/frontend/src/components/pages/ConfigurationPage.scss +++ b/frontend/src/components/pages/ConfigurationPage.scss @@ -10,16 +10,10 @@ .configuration-pane { display: flex; justify-content: center; - height: 100%; - padding-top: 100px; .section-content { - background-color: $color-primary-3; margin-top: 15px; - } - - .section-table table { - background-color: red !important; + background-color: $color-primary-3; } .section-footer { @@ -27,4 +21,3 @@ } } } - diff --git a/frontend/src/components/pages/MainPage.js b/frontend/src/components/pages/MainPage.js index c4dcd20..5d42f4d 100644 --- a/frontend/src/components/pages/MainPage.js +++ b/frontend/src/components/pages/MainPage.js @@ -16,6 +16,7 @@ */ import React, {Component} from "react"; +import {ReflexContainer, ReflexElement, ReflexSplitter} from "react-reflex"; import {Route, Switch} from "react-router-dom"; import Filters from "../dialogs/Filters"; import Header from "../Header"; @@ -29,10 +30,22 @@ import StreamsPane from "../panels/StreamsPane"; import Timeline from "../Timeline"; import "./common.scss"; import "./MainPage.scss"; +import 'react-reflex/styles.css' class MainPage extends Component { - state = {}; + state = { + timelineHeight: 175 + }; + + handleTimelineResize = (e) => { + if (this.timelineTimeoutHandle) { + clearTimeout(this.timelineTimeoutHandle); + } + + this.timelineTimeoutHandle = setTimeout(() => + this.setState({timelineHeight: e.domElement.clientHeight}), 100); + }; render() { let modal; @@ -41,34 +54,40 @@ class MainPage extends Component { } return ( - <div className="page main-page"> - <div className="page-header"> + <ReflexContainer orientation="horizontal" className="page main-page"> + <ReflexElement className="page-header"> <Header onOpenFilters={() => this.setState({filterWindowOpen: true})} configured={true}/> - </div> + {modal} + </ReflexElement> - <div className="page-content"> - <div className="pane connections-pane"> - <Connections onSelected={(c) => this.setState({selectedConnection: c})}/> - </div> - <div className="pane details-pane"> - <Switch> - <Route path="/searches" children={<SearchPane/>}/> - <Route path="/pcaps" children={<PcapsPane/>}/> - <Route path="/rules" children={<RulesPane/>}/> - <Route path="/services" children={<ServicesPane/>}/> - <Route exact path="/connections/:id" - children={<StreamsPane connection={this.state.selectedConnection}/>}/> - <Route children={<MainPane version={this.props.version}/>}/> - </Switch> - </div> + <ReflexElement className="page-content" flex={1}> + <ReflexContainer orientation="vertical" className="page-content"> + <ReflexElement className="pane connections-pane"> + <Connections onSelected={(c) => this.setState({selectedConnection: c})}/> + </ReflexElement> - {modal} - </div> + <ReflexSplitter/> + + <ReflexElement className="pane details-pane"> + <Switch> + <Route path="/searches" children={<SearchPane/>}/> + <Route path="/pcaps" children={<PcapsPane/>}/> + <Route path="/rules" children={<RulesPane/>}/> + <Route path="/services" children={<ServicesPane/>}/> + <Route exact path="/connections/:id" + children={<StreamsPane connection={this.state.selectedConnection}/>}/> + <Route children={<MainPane version={this.props.version}/>}/> + </Switch> + </ReflexElement> + </ReflexContainer> + </ReflexElement> + + <ReflexSplitter propagate={true}/> - <div className="page-footer"> - <Timeline/> - </div> - </div> + <ReflexElement className="page-footer" onResize={this.handleTimelineResize}> + <Timeline height={this.state.timelineHeight}/> + </ReflexElement> + </ReflexContainer> ); } } diff --git a/frontend/src/components/pages/MainPage.scss b/frontend/src/components/pages/MainPage.scss index 4ca54c0..4fc5853 100644 --- a/frontend/src/components/pages/MainPage.scss +++ b/frontend/src/components/pages/MainPage.scss @@ -1,25 +1,25 @@ @import "../../colors"; .main-page { + .page-header { + min-height: 80px; + } + + .page-footer { + overflow: hidden !important; + min-height: 175px; + } + .page-content { - display: flex; - flex: 1; - padding: 0 15px; - background-color: $color-primary-2; + padding: 0 7.5px; .connections-pane { - flex: 1 0; margin-right: 7.5px; } .details-pane { - position: relative; - flex: 1 1; + overflow: hidden; margin-left: 7.5px; } } - - .page-footer { - flex: 0; - } } diff --git a/frontend/src/components/pages/common.scss b/frontend/src/components/pages/common.scss index fcf5c20..2b0cd05 100644 --- a/frontend/src/components/pages/common.scss +++ b/frontend/src/components/pages/common.scss @@ -1,16 +1,3 @@ .page { - position: relative; - display: flex; - flex-direction: column; - height: 100vh; - - .page-header, - .page-footer { - flex: 0; - } - - .page-content { - overflow: hidden; - flex: 1; - } + height: 100vh !important; } diff --git a/frontend/src/components/panels/StreamsPane.scss b/frontend/src/components/panels/StreamsPane.scss index 1f641f3..1d8a250 100644 --- a/frontend/src/components/panels/StreamsPane.scss +++ b/frontend/src/components/panels/StreamsPane.scss @@ -34,6 +34,9 @@ font-size: 11px; margin-top: 6px; margin-left: -10px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .connection-message-actions { @@ -99,6 +102,9 @@ font-size: 12px; padding-top: 7px; padding-left: 25px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .header-actions { diff --git a/frontend/src/index.scss b/frontend/src/index.scss index 1378d81..8389798 100644 --- a/frontend/src/index.scss +++ b/frontend/src/index.scss @@ -49,6 +49,10 @@ a { background: $color-secondary-2; } +::-webkit-scrollbar-corner { + background-color: $color-primary-3; +} + .clickable { cursor: pointer; } @@ -78,15 +82,37 @@ a { color: $color-primary-1; } +.reflex-container.horizontal > .reflex-splitter { + width: auto; + margin: 0 15px; + border-top: 2px solid $color-primary-3; + border-bottom: 2px solid $color-primary-3; +} + +.reflex-container.horizontal > .reflex-splitter:hover, +.reflex-container.horizontal > .reflex-splitter.active { + border-top: 2px solid $color-secondary-2; + border-bottom: 2px solid $color-secondary-2; +} + +.reflex-container.vertical > .reflex-splitter { + border-right: 2px solid $color-primary-3; + border-left: 2px solid $color-primary-3; +} + +.reflex-container.vertical > .reflex-splitter:hover, +.reflex-container.vertical > .reflex-splitter.active { + border-right: 2px solid $color-secondary-2; + border-left: 2px solid $color-secondary-2; +} + @keyframes pulse { 0% { opacity: 1; } - 50% { opacity: 0.3; } - 100% { opacity: 1; } diff --git a/frontend/yarn.lock b/frontend/yarn.lock index e3cade9..e9f01ac 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1123,6 +1123,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.2.0": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740" + integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.10.4", "@babel/template@^7.4.0", "@babel/template@^7.8.6": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" @@ -5313,6 +5320,11 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-node-dimensions@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz#fb7b4bb57060fb4247dd51c9d690dfbec56b0823" + integrity sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ== + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -7226,6 +7238,11 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "^3.0.0" +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -9307,7 +9324,7 @@ prop-types-extra@^1.1.0: react-is "^16.3.2" warning "^4.0.0" -prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -9603,6 +9620,16 @@ react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4: resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== +react-measure@^2.0.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.5.2.tgz#4ffc410e8b9cb836d9455a9ff18fc1f0fca67f89" + integrity sha512-M+rpbTLWJ3FD6FXvYV6YEGvQ5tMayQ3fGrZhRPHrE9bVlBYfDCLuDcgNttYfk8IqfOI03jz6cbpqMRTUclQnaA== + dependencies: + "@babel/runtime" "^7.2.0" + get-node-dimensions "^1.2.1" + prop-types "^15.6.2" + resize-observer-polyfill "^1.5.0" + react-overlays@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-4.1.0.tgz#755a890519b02e3904845172d5223ff2dfb1bb29" @@ -9617,6 +9644,16 @@ react-overlays@^4.1.0: uncontrollable "^7.0.0" warning "^4.0.3" +react-reflex@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/react-reflex/-/react-reflex-3.1.0.tgz#37ccc372afcc6c0929f122bb71f0ab4359722f23" + integrity sha512-TK06JGD+AWOhjQmQFpK/SX6JT36SSqKd1HvD83tAT1gdXVGySJVWMoDhh5N1dA1Op9ae+1cnbe1vFVFIumzLIQ== + dependencies: + "@babel/runtime" "^7.0.0" + lodash.throttle "^4.1.1" + prop-types "^15.5.8" + react-measure "^2.0.2" + react-router-dom@^5.1.2: version "5.2.0" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662" @@ -10069,6 +10106,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +resize-observer-polyfill@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" |