More work and styling of monkey run page components

This commit is contained in:
VakarisZ 2020-08-25 11:30:12 +03:00
parent 522644238b
commit e42c4a0fa2
13 changed files with 153 additions and 49 deletions

View File

@ -2,42 +2,53 @@ import {Button, Card, Nav} from 'react-bootstrap';
import CopyToClipboard from 'react-copy-to-clipboard'; import CopyToClipboard from 'react-copy-to-clipboard';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faClipboard} from '@fortawesome/free-solid-svg-icons/faClipboard'; import {faClipboard} from '@fortawesome/free-solid-svg-icons/faClipboard';
import React, {useState} from 'react'; import React, {useEffect, useState} from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
export default function commandDisplay(props) { export default function commandDisplay(props) {
const [selectedVariant, setSelectedVariant] = useState(props.commands[0].name); const [selectedCommand, setSelectedCommand] = useState(props.commands[0]);
function setSelectedCommandByName(type){
setSelectedCommand(getCommandByName(props.commands, type));
}
function getCommandByName(commands, type){
return commands.find((command) => {return command.type === type});
}
useEffect(() => {
let sameTypeCommand = getCommandByName(props.commands, selectedCommand.type);
if( sameTypeCommand !== undefined){
setSelectedCommand(sameTypeCommand);
} else {
setSelectedCommand(props.commands[0]);
}
}, [props.commands]);
function renderNav() { function renderNav() {
return ( return (
<Nav variant='pills' fill activeKey={selectedVariant} onSelect={setSelectedVariant}> <Nav variant='pills' fill activeKey={selectedCommand.type} onSelect={setSelectedCommandByName}>
{props.commands.map(command => { {props.commands.map(command => {
return ( return (
<Nav.Item key={command.name}> <Nav.Item key={command.type}>
<Nav.Link eventKey={command.name}>{command.name}</Nav.Link> <Nav.Link eventKey={command.type}>{command.type}</Nav.Link>
</Nav.Item>); </Nav.Item>);
})} })}
</Nav>); </Nav>);
} }
function getCommandByName(name, commands) {
commands.forEach((command) => {
})
}
return ( return (
<> <>
{renderNav()} {renderNav()}
<Card style={{'margin': '0.5em'}}> <Card style={{'margin': '0.5em'}}>
<div style={{'overflow': 'auto', 'padding': '0.5em'}}> <div style={{'overflow': 'auto', 'padding': '0.5em'}}>
<CopyToClipboard text={props.commands[0].name} className="pull-right btn-sm"> <CopyToClipboard text={selectedCommand.type} className="pull-right btn-sm">
<Button style={{margin: '-0.5em'}} title="Copy to Clipboard"> <Button style={{margin: '-0.5em'}} title="Copy to Clipboard">
<FontAwesomeIcon icon={faClipboard}/> <FontAwesomeIcon icon={faClipboard}/>
</Button> </Button>
</CopyToClipboard> </CopyToClipboard>
<code>{props.commands[0].command}</code> <code>{selectedCommand.command}</code>
</div> </div>
</Card> </Card>
</> </>
@ -46,7 +57,7 @@ export default function commandDisplay(props) {
commandDisplay.propTypes = { commandDisplay.propTypes = {
commands: PropTypes.arrayOf(PropTypes.exact({ commands: PropTypes.arrayOf(PropTypes.exact({
name: PropTypes.string, type: PropTypes.string,
command: PropTypes.string command: PropTypes.string
})) }))
} }

View File

@ -37,11 +37,11 @@ const getContents = (props) => {
function generateCommands() { function generateCommands() {
if(osType === OS_TYPES.WINDOWS_64 || osType === OS_TYPES.WINDOWS_32) { if(osType === OS_TYPES.WINDOWS_64 || osType === OS_TYPES.WINDOWS_32) {
return [{name: 'CMD', command: GenerateLocalWindowsCmd(selectedIp, osType)}, return [{type: 'CMD', command: GenerateLocalWindowsCmd(selectedIp, osType)},
{name: 'Powershell', command: GenerateLocalWindowsPowershell(selectedIp, osType)}] {type: 'Powershell', command: GenerateLocalWindowsPowershell(selectedIp, osType)}]
} else { } else {
return [{name: 'CURL', command: GenerateLocalLinuxCurl(selectedIp, osType)}, return [{type: 'CURL', command: GenerateLocalLinuxCurl(selectedIp, osType)},
{name: 'WGET', command: GenerateLocalLinuxWget(selectedIp, osType)}] {type: 'WGET', command: GenerateLocalLinuxWget(selectedIp, osType)}]
} }
} }

View File

@ -3,6 +3,10 @@ import NextSelectionButton from '../../ui-components/inline-selection/NextSelect
import LocalManualRunOptions from './LocalManualRunOptions'; import LocalManualRunOptions from './LocalManualRunOptions';
import AuthComponent from '../../AuthComponent'; import AuthComponent from '../../AuthComponent';
import BackButton from '../../ui-components/inline-selection/BackButton'; import BackButton from '../../ui-components/inline-selection/BackButton';
import {faLaptopCode} from '@fortawesome/free-solid-svg-icons/faLaptopCode';
import {faNetworkWired} from '@fortawesome/free-solid-svg-icons/faNetworkWired';
import {faCogs} from '@fortawesome/free-solid-svg-icons/faCogs';
import {Container} from 'react-bootstrap';
function ManualRunOptions(props) { function ManualRunOptions(props) {
@ -41,16 +45,22 @@ function ManualRunOptions(props) {
function getDefaultContents() { function getDefaultContents() {
return ( return (
<div className={`container inline-selection-component`}> <Container className={'inline-selection-component'}>
<NextSelectionButton text={'Local'} onButtonClick={() => { <NextSelectionButton text={'Local'}
setComponent(LocalManualRunOptions, {ips: ips, setComponent: setComponent}) description={'Run on a machine via command.'}
}}/> icon={faLaptopCode}
<NextSelectionButton text={'Remote'} onButtonClick={() => { onButtonClick={() => {setComponent(LocalManualRunOptions,
}}/> {ips: ips, setComponent: setComponent})}}/>
<NextSelectionButton text={'Automation'} onButtonClick={() => { <NextSelectionButton text={'Remote'}
}}/> description={'Run using remote command execution.'}
icon={faNetworkWired}
onButtonClick={() => {}}/>
<NextSelectionButton text={'Automation'}
description={'Run using automation tools like ansible or chef.'}
icon={faCogs}
onButtonClick={() => {}}/>
<BackButton onClick={props.disableManualOptions} /> <BackButton onClick={props.disableManualOptions} />
</div> </Container>
); );
} }

View File

@ -11,7 +11,7 @@ export default function DropdownSelect(props) {
} else if (typeof data === 'object') { } else if (typeof data === 'object') {
return generateDropdownItemsFromObject(data); return generateDropdownItemsFromObject(data);
} else { } else {
throw "Component can only generate dropdown intems from lists and objects." throw 'Component can only generate dropdown items from arrays and objects.'
} }
} }
@ -35,7 +35,8 @@ export default function DropdownSelect(props) {
return ( return (
<Dropdown.Item onClick={() => { setSelectedOption(key); <Dropdown.Item onClick={() => { setSelectedOption(key);
props.onClick(key)}} props.onClick(key)}}
active={(key === selectedOption)}> active={(key === selectedOption)}
key={value}>
{value} {value}
</Dropdown.Item>); </Dropdown.Item>);
} }

View File

@ -1,12 +1,19 @@
import {Button} from 'react-bootstrap'; import {Button, Col, Row} from 'react-bootstrap';
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faCaretLeft} from '@fortawesome/free-solid-svg-icons/faCaretLeft';
export default function backButton(props) { export default function backButton(props) {
return ( return (
<Button variant={'secondary'} onClick={props.onClick}> <Row>
Back <Col lg={8} md={10} sm={12}>
</Button> <Button variant={'outline-dark'} onClick={props.onClick} className={'back-button'}>
<FontAwesomeIcon icon={faCaretLeft} />
<h1>Back</h1>
</Button>
</Col>
</Row>
) )
} }

View File

@ -2,15 +2,16 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import BackButton from './BackButton'; import BackButton from './BackButton';
import ManualRunOptions from '../../pages/RunMonkeyPage/ManualRunOptions'; import ManualRunOptions from '../../pages/RunMonkeyPage/ManualRunOptions';
import Container from 'react-bootstrap';
export default function InlineSelection(WrappedComponent, props, previousComponent){ export default function InlineSelection(WrappedComponent, props, previousComponent){
return ( return (
<div className={`container inline-selection-component`}> <Container className={'inline-selection-component'}>
{previousComponent === undefined ? '' : {previousComponent === undefined ? '' :
<BackButton onClick={() => {setPreviousComponent(props, previousComponent)}}/>} <BackButton onClick={() => {setPreviousComponent(props, previousComponent)}}/>}
<WrappedComponent {...props}/> <WrappedComponent {...props}/>
</div> </Container>
) )
} }

View File

@ -1,17 +1,31 @@
import {Button} from 'react-bootstrap'; import {Button, Row, Col} from 'react-bootstrap';
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faAngleRight} from '@fortawesome/free-solid-svg-icons';
export default function nextSelectionButton(props) { export default function nextSelectionButton(props) {
console.log(props);
let description = props.description !== undefined ? (<p>{props.description}</p>) : ''
let icon = props.icon !== undefined ? (<FontAwesomeIcon icon={props.icon}/>) : ''
return ( return (
<Button variant={'outline-monkey'} size='lg' className={'selection-button'} <Row>
onClick={props.onButtonClick}> <Col lg={8} md={10} sm={12}>
{props.text} <Button variant={'outline-monkey'} size='lg' className={'selection-button'}
</Button> onClick={props.onButtonClick}>
{icon}
<h1>{props.text}</h1>
{description}
<FontAwesomeIcon icon={faAngleRight} className={'angle-right'}/>
</Button>
</Col>
</Row>
) )
} }
nextSelectionButton.propTypes = { nextSelectionButton.propTypes = {
text: PropTypes.string, text: PropTypes.string,
description: PropTypes.string,
icon: FontAwesomeIcon,
onButtonClick: PropTypes.func onButtonClick: PropTypes.func
} }

View File

@ -11,7 +11,9 @@
@import 'components/InfoPane'; @import 'components/InfoPane';
@import 'components/PreviewPane'; @import 'components/PreviewPane';
@import 'components/AdvancedMultiSelect'; @import 'components/AdvancedMultiSelect';
@import 'components/InlineSelection'; @import 'components/inline-selection/InlineSelection';
@import 'components/inline-selection/NextSelectionButton';
@import 'components/inline-selection/BackButton';
// Define custom elements after bootstrap import // Define custom elements after bootstrap import

View File

@ -1,8 +0,0 @@
.inline-selection-component.container {
display: flex;
justify-content: center;
}
.inline-selection-component.container .selection-button{
margin: 0 5px 0 5px;
}

View File

@ -0,0 +1,20 @@
.inline-selection-component .back-button {
width: 100%;
text-align: left;
}
.inline-selection-component .back-button h1{
font-size: 1.3em;
margin-top: 5px;
margin-bottom: 5px;
text-align: left;
display: inline-block;
}
.inline-selection-component .back-button svg{
font-size: 1.5em;
display: inline-block;
margin-right: 10px;
position: relative;
top: 1px;
}

View File

@ -0,0 +1,12 @@
//.inline-selection-component.container {
// display: flex;
// justify-content: center;
//}
//
//.inline-selection-component.container .selection-button{
// margin: 0 5px 0 5px;
//}
.inline-selection-component .selection-button {
width: 100%;
}

View File

@ -0,0 +1,34 @@
.inline-selection-component .selection-button {
width: 100%;
text-align: left;
margin-bottom: 20px;
padding-right: 40px;
}
.inline-selection-component .selection-button svg,
.inline-selection-component .selection-button h1 {
display: inline-block;
}
.inline-selection-component .selection-button h1 {
margin: 0;
font-size: 1.3em;
}
.inline-selection-component .selection-button p {
margin: 0;
font-size: 0.8em;
}
.inline-selection-component .selection-button svg {
margin-bottom: 1px;
margin-right: 7px;
}
.inline-selection-component .selection-button .angle-right {
display: inline-block;
position: absolute;
right: 23px;
top: 22%;
font-size: 1.7em;
}