Created
November 20, 2019 15:04
-
-
Save akkikumar72/d37ce0c6022bf262381d6995a00f69b5 to your computer and use it in GitHub Desktop.
Using useReducer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useReducer } from 'react'; | |
import { useSelector, useDispatch } from 'react-redux'; | |
import Select from 'react-select'; | |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | |
import { faSpinner } from '@fortawesome/free-solid-svg-icons'; | |
import { scanRepo } from '../../actions/scanActions'; | |
import { Redirect } from 'react-router-dom'; | |
import './scan.scss'; | |
import Toggle from '../../common/toggle/toggle'; | |
import { RenderError } from '../../common/notification/notification'; | |
import { NOTIFICATION_ID } from '../../actions/scanActions'; | |
import DropdownIndicator from '../../common/dropDownIndicator/dropDownIndicator'; | |
const options = [{ value: 'all', label: 'All' }, { value: 'soapui', label: 'SoapUI' }]; //TODO: This should come from BE | |
const intialState = { | |
scanType: [0], | |
notify: true, | |
scanName: '', | |
repoUrl: '', | |
branch: '', | |
accessToken: '', | |
userName: '', | |
password: '', | |
redirectToScanList: false | |
}; | |
const reducer = (state, action) => { | |
switch (action.type) { | |
case 'SETSCANNAME': | |
return { ...state, scanName: action.value }; | |
case 'SETBRANCH': | |
return { ...state, branch: action.value }; | |
case 'SETSCANTYPE': | |
return { ...state, scanType: action.value }; | |
case 'SETNOTIFY': | |
return { ...state, notify: !state.notify }; | |
case 'SETREPORTURL': | |
return { ...state, repoUrl: action.value }; | |
default: | |
throw new Error(); | |
} | |
}; | |
const ScanForm = () => { | |
const dispatchForRedux = useDispatch(); | |
const { scan } = useSelector((state) => ({ scan: state.scan })); | |
const { notifications } = useSelector((state) => ({ notifications: state.notifications })); | |
const [state, dispatch] = useReducer(reducer, intialState); | |
//TODO convert it to useReducer | |
const [accessToken, setAccessToken] = useState(''); | |
const [userName, setUserName] = useState(''); | |
const [password, setPassword] = useState(''); | |
const [redirectToScanList, setRedirectToScanList] = useState(false); | |
const { scanType, scanName, branch, notify, repoUrl } = state; | |
if ((scan.scanInfo && scan.scanInfo.status === 'scanning') || redirectToScanList) { | |
return <Redirect to='/scan-list' />; | |
} | |
const handleScanTypeChange = (scanType) => { | |
dispatch({ | |
type: 'SETSCANTYPE', | |
value: scanType | |
}); | |
}; | |
const toggleNotify = () => { | |
dispatch({ type: 'SETNOTIFY' }); | |
}; | |
const isFormValid = () => { | |
return scanType && scanName && repoUrl; | |
}; | |
const renderSaveButtonLabel = () => { | |
if (scan.isSaving) { | |
return ( | |
<> | |
<FontAwesomeIcon className='icon' icon={faSpinner} spin /> Saving | |
</> | |
); | |
} else { | |
return <>Save</>; | |
} | |
}; | |
const renderSaveAndScanButtonLabel = () => { | |
if (scan.isScanAndSaving) { | |
return ( | |
<> | |
<FontAwesomeIcon className='icon' icon={faSpinner} spin /> Scan & Saving | |
</> | |
); | |
} else { | |
return <>Scan & Save</>; | |
} | |
}; | |
const handleSubmit = () => { | |
const formData = { | |
scanType, //TODO:might need to change when it is decided in the BE | |
name: scanName.trim(), | |
notify, //TODO:might need to change when it is decided in the BE | |
url: repoUrl.trim(), | |
branch: branch.trim(), | |
secret: accessToken.trim(), | |
username: userName.trim(), | |
password: password.trim() | |
}; | |
dispatchForRedux(scanRepo(formData)); | |
}; | |
console.log(state); | |
return ( | |
<div className='page-wrapper'> | |
<div className='scan'> | |
<div className='main-header'> | |
<div className='header'>Scan Configuration</div> | |
<button className='button button-small-ghost cancel' onClick={() => setRedirectToScanList(true)}> | |
Cancel | |
</button> | |
<button className='button button-small save' disabled={!isFormValid()} onClick={handleSubmit}> | |
{renderSaveButtonLabel()} | |
</button> | |
<button className='button button-small save-scan' disabled={!isFormValid()} onClick={handleSubmit}> | |
{renderSaveAndScanButtonLabel()} | |
</button> | |
</div> | |
<div className='form-info'> | |
<Toggle id={NOTIFICATION_ID}> | |
<RenderError message={scan.error} notificationId={NOTIFICATION_ID} /> | |
</Toggle> | |
{(!scan.error || !notifications[NOTIFICATION_ID]) && ( | |
<>Enter the required information to scan your repository and retrieve Test Assets.</> | |
)} | |
</div> | |
<div className='row'> | |
<div className='column'> | |
<div className='white-background'> | |
<div className='title'>Details</div> | |
<div> | |
<label htmlFor='scan-type' className='form-label required-field'> | |
Select Scan Type | |
</label> | |
<Select | |
className='select-container' | |
classNamePrefix='scan-type' | |
value={scanType} | |
onChange={handleScanTypeChange} | |
options={options} | |
isMulti={true} | |
placeholder='' | |
isSearchable={false} | |
components={{ DropdownIndicator }} | |
/> | |
</div> | |
<div className='form-field'> | |
<label htmlFor='scan-name' className='form-label required-field'> | |
Name Scan | |
</label> | |
<input | |
type='text' | |
className='form-control' | |
value={state.scanName} | |
onChange={(e) => dispatch({ type: 'SETSCANNAME', value: e.target.value })} | |
/> | |
</div> | |
<div className='form-field form-info'> | |
<div>Depending on repository size, scanning may take some time.</div> | |
<div className='notify'> | |
<div className='checkbox-wrapper'> | |
<input type='checkbox' id='notify' name='notify' checked={notify} onChange={toggleNotify} /> | |
<label htmlFor='notify' /> | |
</div> | |
<div className='notify-label'> | |
<label htmlFor='notify'>Send notification when scan is complete </label> | |
</div> | |
</div> | |
</div> | |
<div className='form-field'> | |
<label htmlFor='repo-url' className='form-label required-field'> | |
Repository URL | |
</label> | |
<input | |
type='text' | |
className='form-control' | |
value={repoUrl} | |
onChange={(e) => dispatch({ type: 'SETREPORTURL', value: e.target.value })} | |
/> | |
</div> | |
<div className='form-field'> | |
<label htmlFor='branch' className='form-label'> | |
Specify Branch | |
</label> | |
<input | |
type='text' | |
className='form-control' | |
value={branch} | |
onChange={(e) => dispatch({ type: 'SETBRANCH', value: e.target.value })} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className='column'> | |
<div className='white-background'> | |
<div className='title'>Credentials</div> | |
<div className='form-info'>If required by your repository, enter the appropriate credentials.</div> | |
<div className='form-field'> | |
<label htmlFor='access-token' className='form-label'> | |
Personal Access Token | |
</label> | |
<input | |
type='password' | |
className='form-control' | |
value={accessToken} | |
onChange={(e) => setAccessToken(e.target.value)} | |
/> | |
</div> | |
<div className='form-field'> | |
<label htmlFor='username' className='form-label or'> | |
- Or - | |
</label> | |
</div> | |
<div className='form-field'> | |
<label htmlFor='username' className='form-label'> | |
Username | |
</label> | |
<input | |
type='text' | |
className='form-control' | |
value={userName} | |
onChange={(e) => setUserName(e.target.value)} | |
disabled={accessToken} | |
/> | |
</div> | |
<div className='form-field'> | |
<label htmlFor='password' className='form-label'> | |
Password | |
</label> | |
<input | |
type='password' | |
className='form-control' | |
value={password} | |
onChange={(e) => setPassword(e.target.value)} | |
disabled={accessToken} | |
/> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div className='add-tags'> | |
<div className='row'> | |
<div className='column'> | |
<div className='white-background'> | |
<div className='title'>Add Tags</div> | |
<div className='form-info'>Apply tags to your assets to help identify and organize them.</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
); | |
}; | |
export default ScanForm; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment