Island UI: fix a bug that broke completed step checkmarks in the side navigation

This commit is contained in:
VakarisZ 2021-07-15 11:35:48 +03:00
parent e9094bdfd6
commit 1a7b513ca3
3 changed files with 103 additions and 96 deletions

View File

@ -29,6 +29,7 @@ import {DisabledSidebarLayoutComponent} from "./layouts/DisabledSidebarLayoutCom
import {CompletedSteps} from "./side-menu/CompletedSteps"; import {CompletedSteps} from "./side-menu/CompletedSteps";
import Timeout = NodeJS.Timeout; import Timeout = NodeJS.Timeout;
import IslandHttpClient from "./IslandHttpClient"; import IslandHttpClient from "./IslandHttpClient";
import _ from "lodash";
let notificationIcon = require('../images/notification-logo-512x512.png'); let notificationIcon = require('../images/notification-logo-512x512.png');
@ -91,18 +92,13 @@ class AppComponent extends AuthComponent {
this.authFetch('/api') this.authFetch('/api')
.then(res => res.json()) .then(res => res.json())
.then(res => { .then(res => {
let completedSteps = CompletedSteps.buildFromResponse(res.completed_steps);
// This check is used to prevent unnecessary re-rendering // This check is used to prevent unnecessary re-rendering
let isChanged = false; if (_.isEqual(this.state.completedSteps, completedSteps)) {
for (let step in this.state.completedSteps) { return;
if (this.state.completedSteps[step] !== res['completed_steps'][step]) {
isChanged = true;
break;
}
}
if (isChanged) {
this.setState({completedSteps: res['completed_steps']});
this.showInfectionDoneNotification();
} }
this.setState({completedSteps: completedSteps});
this.showInfectionDoneNotification();
}); });
} }
) )

View File

@ -22,91 +22,92 @@ type Props = {
const SideNavComponent = ({disabled=false, completedSteps}: Props) => { const SideNavComponent = ({disabled=false, completedSteps}: Props) => {
return (
<>
<NavLink to={'/'} exact={true}>
<div className='header'>
<img alt='logo' src={logoImage} style={{width: '5vw', margin: '15px'}}/>
<img src={infectionMonkeyImage} style={{width: '15vw'}} alt='Infection Monkey'/>
</div>
</NavLink>
<ul className='navigation'> return (
<li> <>
<NavLink to='/run-monkey' className={getNavLinkClass()}> <NavLink to={'/'} exact={true}>
<span className='number'>1.</span> <div className='header'>
Run Monkey <img alt='logo' src={logoImage} style={{width: '5vw', margin: '15px'}}/>
{completedSteps.runMonkey ? <img src={infectionMonkeyImage} style={{width: '15vw'}} alt='Infection Monkey'/>
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
: ''}
</NavLink>
</li>
<li>
<NavLink to='/infection/map' className={getNavLinkClass()}>
<span className='number'>2.</span>
Infection Map
{completedSteps.infectionDone ?
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
: ''}
</NavLink>
</li>
<li>
<NavLink to='/report/security'
className={getNavLinkClass()}
isActive={(_match, location) => {
return (isReportRoute(location.pathname))
}}>
<span className='number'>3.</span>
Security Reports
{completedSteps.reportDone ?
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
: ''}
</NavLink>
</li>
<li>
<NavLink to='/start-over' className={getNavLinkClass()}>
<span className='number'><FontAwesomeIcon icon={faUndo} style={{'marginLeft': '-1px'}}/></span>
Start Over
</NavLink>
</li>
</ul>
<hr/>
<ul>
<li><NavLink to='/configure'
className={getNavLinkClass()}>
Configuration
</NavLink></li>
<li><NavLink to='/infection/telemetry'
className={getNavLinkClass()}>
Logs
</NavLink></li>
</ul>
<hr/>
<div className='guardicore-link text-center' style={{'marginBottom': '0.5em'}}>
<span>Powered by</span>
<a href='http://www.guardicore.com' rel='noopener noreferrer' target='_blank'>
<img src={guardicoreLogoImage} alt='GuardiCore'/>
</a>
</div> </div>
<div className='license-link text-center'> </NavLink>
<a href='https://www.guardicore.com/infectionmonkey/docs' rel="noopener noreferrer" target="_blank">
<FontAwesomeIcon icon={faExternalLinkAlt} /> Documentation
</a>
<br/>
<NavLink to='/license'>License</NavLink>
</div>
<VersionComponent/>
</>);
function getNavLinkClass() { <ul className='navigation'>
if(disabled){ <li>
return `nav-link disabled` <NavLink to='/run-monkey' className={getNavLinkClass()}>
} else { <span className='number'>1.</span>
return '' Run Monkey
} {completedSteps.runMonkey ?
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
: ''}
</NavLink>
</li>
<li>
<NavLink to='/infection/map' className={getNavLinkClass()}>
<span className='number'>2.</span>
Infection Map
{completedSteps.infectionDone ?
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
: ''}
</NavLink>
</li>
<li>
<NavLink to='/report/security'
className={getNavLinkClass()}
isActive={(_match, location) => {
return (isReportRoute(location.pathname))
}}>
<span className='number'>3.</span>
Security Reports
{completedSteps.reportDone ?
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
: ''}
</NavLink>
</li>
<li>
<NavLink to='/start-over' className={getNavLinkClass()}>
<span className='number'><FontAwesomeIcon icon={faUndo} style={{'marginLeft': '-1px'}}/></span>
Start Over
</NavLink>
</li>
</ul>
<hr/>
<ul>
<li><NavLink to='/configure'
className={getNavLinkClass()}>
Configuration
</NavLink></li>
<li><NavLink to='/infection/telemetry'
className={getNavLinkClass()}>
Logs
</NavLink></li>
</ul>
<hr/>
<div className='guardicore-link text-center' style={{'marginBottom': '0.5em'}}>
<span>Powered by</span>
<a href='http://www.guardicore.com' rel='noopener noreferrer' target='_blank'>
<img src={guardicoreLogoImage} alt='GuardiCore'/>
</a>
</div>
<div className='license-link text-center'>
<a href='https://www.guardicore.com/infectionmonkey/docs' rel="noopener noreferrer" target="_blank">
<FontAwesomeIcon icon={faExternalLinkAlt} /> Documentation
</a>
<br/>
<NavLink to='/license'>License</NavLink>
</div>
<VersionComponent/>
</>);
function getNavLinkClass() {
if(disabled){
return `nav-link disabled`
} else {
return ''
} }
}
} }
export default SideNavComponent; export default SideNavComponent;

View File

@ -9,14 +9,24 @@ export class CompletedSteps {
public constructor(runServer?: boolean, public constructor(runServer?: boolean,
runMonkey?: boolean, runMonkey?: boolean,
infectinDone?: boolean, infectinDone?: boolean,
reportDone?: boolean, reportDone?: boolean) {
isLoggedIn?: boolean,
needsRegistration?: boolean) {
this.runServer = runServer || false; this.runServer = runServer || false;
this.runMonkey = runMonkey || false; this.runMonkey = runMonkey || false;
this.infectionDone = infectinDone || false; this.infectionDone = infectinDone || false;
this.reportDone = reportDone || false; this.reportDone = reportDone || false;
this.isLoggedIn = isLoggedIn || false; }
this.needsRegistration = needsRegistration || false;
static buildFromResponse(response: CompletedStepsRequest) {
return new CompletedSteps(response.run_server,
response.run_monkey,
response.infection_done,
response.report_done);
} }
} }
type CompletedStepsRequest = {
run_server: boolean,
run_monkey: boolean,
infection_done: boolean,
report_done: boolean
}