From 19b719d1a5056aad8da19d73071fef358acfbff8 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 5 Apr 2020 23:05:58 -0500 Subject: [PATCH] Password UI --- .../ConfigurationItem/ConfigurationItem.js | 51 ++++++- src/containers/UI/Password/Password.css | 33 +++++ src/containers/UI/Password/Password.js | 133 ++++++++++++++++++ src/utils.js | 1 - 4 files changed, 210 insertions(+), 8 deletions(-) create mode 100644 src/containers/UI/Password/Password.css create mode 100644 src/containers/UI/Password/Password.js diff --git a/src/containers/Configuration/ConfigurationItem/ConfigurationItem.js b/src/containers/Configuration/ConfigurationItem/ConfigurationItem.js index 79c2613..b889506 100644 --- a/src/containers/Configuration/ConfigurationItem/ConfigurationItem.js +++ b/src/containers/Configuration/ConfigurationItem/ConfigurationItem.js @@ -4,13 +4,18 @@ import CheckBox from '../../../components/UI/CheckBox/CheckBox'; import {connect} from 'react-redux'; import {faInfoCircle} from '@fortawesome/free-solid-svg-icons'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; -import {notifyInfo} from '../../../redux/actions/error_actions'; +import { + notifyError, + notifyInfo +} from '../../../redux/actions/error_actions'; import settings from '../../../assets/settings'; import DropDown from '../../../components/UI/DropDown/DropDown'; +import Password from '../../../containers/UI/Password/Password'; const mapDispatchToProps = dispatch => { return { - notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)) + notifyError: msg => dispatch(notifyError(msg)), + notifyInfo: (title, msg) => dispatch(notifyInfo(title, msg)), } }; @@ -68,12 +73,29 @@ export default connect(null, mapDispatchToProps)(props => { break; case 'string': - data = handleChanged(e)} - autoFocus={props.autoFocus} - className={'ConfigurationItemInput'} + if (props.template.subtype === 'password') { + data = ( + handleChanged({ + target: { + type: 'password', + value: s, + }, + })} disabled={props.readOnly} - type={'text'} - value={props.value}/>; + mismatchHandler={() => props.notifyError('Passwords do not match')} + value={props.value} /> + ); + } else { + data = ( + handleChanged(e)} + autoFocus={props.autoFocus} + className={'ConfigurationItemInput'} + disabled={props.readOnly} + type={'text'} + value={props.value}/> + ); + } break; case 'uint8': @@ -132,6 +154,21 @@ export default connect(null, mapDispatchToProps)(props => { ); break; + case 'password': + data = ( + handleChanged({ + target: { + type: 'password', + value: s, + }, + })} + disabled={props.readOnly} + mismatchHandler={() => props.notifyError('Passwords do not match')} + value={props.value} /> + ); + break; + default: data =
{props.value}
; } diff --git a/src/containers/UI/Password/Password.css b/src/containers/UI/Password/Password.css new file mode 100644 index 0000000..6409b49 --- /dev/null +++ b/src/containers/UI/Password/Password.css @@ -0,0 +1,33 @@ +.PasswordOwner { + padding: 0; + width: auto; + height: auto; + display: flex; + justify-content: left; + align-content: center; + flex-direction: row; +} + +input.PasswordInput { + display: block; + margin-right: var(--default_spacing); + padding: 2px; + border-radius: var(--border_radius); + background: rgba(160, 160, 160, 0.1); + border: none; + box-shadow: none; + outline: none; + color: var(--text_color); + box-sizing: border-box; +} + +.PasswordShowHide { + padding-top: 2px; + cursor: pointer; + min-width: 20px; +} + +.PasswordLink { + margin-right: var(--default_spacing); + cursor: pointer; +} diff --git a/src/containers/UI/Password/Password.js b/src/containers/UI/Password/Password.js new file mode 100644 index 0000000..c70641b --- /dev/null +++ b/src/containers/UI/Password/Password.js @@ -0,0 +1,133 @@ +import React, {Component} from 'react'; +import './Password.css'; +import {faEye, faEyeSlash} from '@fortawesome/free-solid-svg-icons'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; + +export default class extends Component { + state = { + button_text: 'clear', + password: '', + password2: '', + show_password: false, + }; + + componentDidMount() { + if (!this.props.value || (this.props.value.length === 0)) { + this.setState({ + ...this.state, + button_text: 'set', + password: '', + password2: '', + show_password: false, + }) + } else { + this.setState({ + ...this.state, + button_text: 'clear', + password: this.props.value, + password2: '', + show_password: false, + }) + } + } + + handleActionClick = () => { + if (!this.props.disabled) { + switch (this.state.button_text) { + case 'clear': + this.setState({ + ...this.state, + button_text: 'set', + password: '', + password2: '', + }); + break; + + case 'confirm': + if (this.state.password === this.state.password2) { + this.props.changed(this.state.password); + this.setState({ + ...this.state, + button_text: 'clear', + password2: '', + }); + } else { + this.setState({ + ...this.state, + button_text: 'set', + password: '', + password2: '', + }, () => { + if (this.props.mismatchHandler) { + this.props.mismatchHandler(); + } + }); + } + break; + + case 'set': + this.setState({ + ...this.state, + button_text: 'confirm', + password2: '', + }); + break; + + default: + return; + } + } + }; + + handlePasswordChanged = e => { + if (this.state.button_text === 'set') { + this.setState({ + ...this.state, + password: e.target.value, + }); + } else if (this.state.button_text === 'confirm') { + this.setState({ + ...this.state, + password2: e.target.value, + }); + } + }; + + handlePasswordKeyUp = e => { + if ((e.keyCode === 13) && ((this.state.button_text === 'confirm') || (this.state.button_text === 'set'))) { + this.handleActionClick(); + } + }; + + handleShowHideClick = () => { + this.setState({ + ...this.state, + show_password: !this.state.show_password, + }); + }; + + render() { + return ( +
+ + {this.state.button_text} + + + + + +
+ ); + } +}; diff --git a/src/utils.js b/src/utils.js index afa6056..11489b8 100644 --- a/src/utils.js +++ b/src/utils.js @@ -79,7 +79,6 @@ export const getIPCRenderer = () => { export const getNewReleases = (existingLocations, newLocations, selectedVersion) => { const ret = []; - console.log(selectedVersion); if (existingLocations && newLocations) { Constants.RELEASE_TYPES.forEach(release => { newLocations[release]