forked from p34709852/monkey
More work and styling of monkey run page components
This commit is contained in:
parent
522644238b
commit
e42c4a0fa2
|
@ -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
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
.inline-selection-component.container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inline-selection-component.container .selection-button{
|
|
||||||
margin: 0 5px 0 5px;
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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%;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue