Separated InternalConfig into separate tabs for easier navigation

This commit is contained in:
VakarisZ 2020-07-24 17:00:08 +03:00
parent 76401f0778
commit ecea415e36
2 changed files with 102 additions and 23 deletions

View File

@ -0,0 +1,69 @@
import Form from 'react-jsonschema-form-bs4';
import React, {useState} from 'react';
import {Nav} from 'react-bootstrap';
const sectionOrder = ['network', 'monkey', 'island_server', 'logging', 'exploits', 'dropper', 'classes', 'general',
'kill_file', 'testing'];
const initialSection = sectionOrder[0];
export default function InternalConfig(props) {
const {
schema,
uiSchema,
onChange,
customFormats,
className,
formData
} = props;
const [selectedSection, setSelectedSection] = useState(initialSection);
const [displayedSchema, setDisplayedSchema] = useState(getSchemaByKey(schema, initialSection));
const [displayedSchemaUi, setDisplayedSchemaUi] = useState(uiSchema[initialSection])
const onInnerDataChange = (innerData) => {
formData[selectedSection] = innerData.formData;
onChange({formData: formData});
}
const setSection = (sectionKey) => {
setSelectedSection(sectionKey);
setDisplayedSchema(getSchemaByKey(schema, sectionKey));
setDisplayedSchemaUi(uiSchema[sectionKey])
}
const renderNav = () => {
return (<Nav variant='tabs'
fill
activeKey={selectedSection} onSelect={setSection}
style={{'marginBottom': '2em'}}
className={'config-nav'}>
{sectionOrder.map(section => {
return (
<Nav.Item>
<Nav.Link eventKey={section}>{getNavTitle(schema, section)}</Nav.Link>
</Nav.Item>);
})}
</Nav>)
}
return (<div>
{renderNav()}
<Form schema={displayedSchema}
uiSchema={displayedSchemaUi}
formData={formData[selectedSection]}
onChange={onInnerDataChange}
customFormats={customFormats}
className={className}
liveValidate>
<button type='submit' className={'hidden'}>Submit</button>
</Form>
</div>)
};
function getSchemaByKey(schema, key) {
let definitions = schema['definitions']
return {definitions: definitions, properties: schema['properties'][key]['properties']}
}
function getNavTitle(schema, key) {
return schema.properties[key].title;
}

View File

@ -10,6 +10,7 @@ import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle';
import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'; import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck';
import {faExclamationCircle} from '@fortawesome/free-solid-svg-icons/faExclamationCircle'; import {faExclamationCircle} from '@fortawesome/free-solid-svg-icons/faExclamationCircle';
import {formValidationFormats} from "../configuration-components/ValidationFormats"; import {formValidationFormats} from "../configuration-components/ValidationFormats";
import InternalConfig from "../configuration-components/InternalConfig";
const ATTACK_URL = '/api/attack'; const ATTACK_URL = '/api/attack';
const CONFIG_URL = '/api/configuration/island'; const CONFIG_URL = '/api/configuration/island';
@ -244,8 +245,8 @@ class ConfigurePageComponent extends AuthComponent {
this.props.onStatusChange(); this.props.onStatusChange();
} }
).then(() => { ).then(() => {
this.removePBAfile(API_PBA_WINDOWS, this.setPbaFilenameWindows) this.removePBAfile(API_PBA_WINDOWS, this.setPbaFilenameWindows)
this.removePBAfile(API_PBA_LINUX, this.setPbaFilenameLinux) this.removePBAfile(API_PBA_LINUX, this.setPbaFilenameLinux)
}); });
this.authFetch(ATTACK_URL, { this.authFetch(ATTACK_URL, {
method: 'POST', method: 'POST',
@ -331,24 +332,33 @@ class ConfigurePageComponent extends AuthComponent {
}; };
renderConfigContent = (displayedSchema) => { renderConfigContent = (displayedSchema) => {
return (<div> let formProperties = {};
{this.renderBasicNetworkWarning()} formProperties['schema'] = displayedSchema
<Form schema={displayedSchema} formProperties['uiSchema'] = UiSchema({
uiSchema={UiSchema({ PBA_linux_filename: this.state.configuration.monkey.post_breach.PBA_linux_filename,
PBA_linux_filename: this.state.configuration.monkey.post_breach.PBA_linux_filename, PBA_windows_filename: this.state.configuration.monkey.post_breach.PBA_windows_filename,
PBA_windows_filename: this.state.configuration.monkey.post_breach.PBA_windows_filename, setPbaFilenameWindows: this.setPbaFilenameWindows,
setPbaFilenameWindows: this.setPbaFilenameWindows, setPbaFilenameLinux: this.setPbaFilenameLinux,
setPbaFilenameLinux: this.setPbaFilenameLinux, selectedSection: this.state.selectedSection
selectedSection: this.state.selectedSection })
})} formProperties['formData'] = this.state.configuration[this.state.selectedSection]
formData={this.state.configuration[this.state.selectedSection]} formProperties['onChange'] = this.onChange
onChange={this.onChange} formProperties['customFormats'] = formValidationFormats
customFormats={formValidationFormats} formProperties['className'] = 'config-form'
className={'config-form'} formProperties['liveValidate'] = true
liveValidate>
<button type='submit' className={'hidden'}>Submit</button> if (this.state.selectedSection === 'internal') {
</Form> return (<InternalConfig {...formProperties}/>)
</div>) } else {
return (
<div>
{this.renderBasicNetworkWarning()}
<Form {...formProperties}>
<button type='submit' className={'hidden'}>Submit</button>
</Form>
</div>
)
}
}; };
setPbaFilenameWindows = (filename) => { setPbaFilenameWindows = (filename) => {
@ -388,9 +398,9 @@ class ConfigurePageComponent extends AuthComponent {
{this.state.sections.map(section => { {this.state.sections.map(section => {
let classProp = section.key.startsWith('basic') ? 'tab-primary' : ''; let classProp = section.key.startsWith('basic') ? 'tab-primary' : '';
return ( return (
<Nav.Item> <Nav.Item>
<Nav.Link className={classProp} eventKey={section.key}>{section.title}</Nav.Link> <Nav.Link className={classProp} eventKey={section.key}>{section.title}</Nav.Link>
</Nav.Item>); </Nav.Item>);
})} })}
</Nav>) </Nav>)
}; };