mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
Fixes for editing users
- edit user dialogs behave as expected - editing own user triggers update of LoginStore and local storage with updated user data
This commit is contained in:
parent
3437e582c7
commit
433c0918f2
6 changed files with 125 additions and 127 deletions
|
@ -19,17 +19,16 @@ import React from 'react';
|
|||
import { Form, Col } from 'react-bootstrap';
|
||||
|
||||
import Dialog from '../common/dialogs/dialog';
|
||||
import NotificationsDataManager from "../common/data-managers/notifications-data-manager";
|
||||
import NotificationsFactory from "../common/data-managers/notifications-factory";
|
||||
|
||||
|
||||
class EditOwnUserDialog extends React.Component {
|
||||
valid: true;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
username: this.props.user.username,
|
||||
id: this.props.user.id,
|
||||
username: "",
|
||||
mail: this.props.user.mail,
|
||||
password: '',
|
||||
oldPassword: '',
|
||||
|
@ -39,9 +38,29 @@ class EditOwnUserDialog extends React.Component {
|
|||
|
||||
onClose(canceled) {
|
||||
if (canceled === false) {
|
||||
if (this.valid) {
|
||||
this.props.onClose(this.state);
|
||||
|
||||
let user = {};
|
||||
user.id = this.props.user.id;
|
||||
user.password = this.state.password;
|
||||
user.oldPassword = this.state.oldPassword;
|
||||
user.confirmPassword = this.state.confirmPassword
|
||||
|
||||
if (this.state.username != null && this.state.username !== this.props.user.username){
|
||||
user.username = this.state.username;
|
||||
}
|
||||
|
||||
if (this.state.mail != null && this.state.mail !== this.props.user.mail){
|
||||
user.mail = this.state.mail;
|
||||
}
|
||||
|
||||
if (this.state.password !== '' && this.state.oldPassword !== '' && this.state.password === this.state.confirmPassword ) {
|
||||
user.password = this.state.password;
|
||||
user.oldPassword = this.state.oldPassword;
|
||||
} else if (this.state.password !== '' && this.state.password !== this.state.confirmPassword) {
|
||||
NotificationsDataManager.addNotification(NotificationsFactory.UPDATE_ERROR('New password not correctly confirmed'));
|
||||
}
|
||||
|
||||
this.props.onClose(user);
|
||||
} else {
|
||||
this.props.onClose();
|
||||
}
|
||||
|
@ -49,42 +68,11 @@ class EditOwnUserDialog extends React.Component {
|
|||
|
||||
handleChange(e) {
|
||||
this.setState({ [e.target.id]: e.target.value });
|
||||
|
||||
// check all controls
|
||||
let username = true;
|
||||
let mail = true;
|
||||
let pw = true;
|
||||
let oldPassword = true;
|
||||
let confirmPassword = true;
|
||||
|
||||
if (this.state.username === '') {
|
||||
username = false;
|
||||
}
|
||||
|
||||
if (this.state.mail === '') {
|
||||
mail = false;
|
||||
}
|
||||
|
||||
if (this.state.password === '') {
|
||||
pw = false;
|
||||
}
|
||||
|
||||
if (this.state.oldPassword === '') {
|
||||
oldPassword = false;
|
||||
}
|
||||
|
||||
if (this.state.confirmPassword === '') {
|
||||
confirmPassword = false;
|
||||
}
|
||||
|
||||
// form is valid if the following condition is met
|
||||
this.valid = username || mail || (oldPassword && pw && confirmPassword);
|
||||
}
|
||||
|
||||
resetState() {
|
||||
this.setState({
|
||||
username: this.props.user.username,
|
||||
id: this.props.user.id,
|
||||
mail: this.props.user.mail,
|
||||
oldPassword: '',
|
||||
confirmPassword: '',
|
||||
|
@ -94,28 +82,28 @@ class EditOwnUserDialog extends React.Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<Dialog show={this.props.show} title="Edit user" buttonTitle="Save" onClose={(c) => this.onClose(c)} onReset={() => this.resetState()} valid={this.valid}>
|
||||
<Dialog show={this.props.show} title="Edit user" buttonTitle="Save" onClose={(c) => this.onClose(c)} onReset={() => this.resetState()} valid={true}>
|
||||
<Form>
|
||||
<Form.Group as={Col} controlId="username">
|
||||
<Form.Label>Username</Form.Label>
|
||||
<Form.Control type="text" value={this.state.username} onChange={(e) => this.handleChange(e)} autocomplete="username" />
|
||||
<Form.Control type="text" placeholder={this.props.user.username} value={this.state.username} onChange={(e) => this.handleChange(e)} autoComplete="username" />
|
||||
<Form.Control.Feedback />
|
||||
</Form.Group>
|
||||
<Form.Group as={Col} controlId="mail">
|
||||
<Form.Label>E-mail</Form.Label>
|
||||
<Form.Control type="text" value={this.state.mail} onChange={(e) => this.handleChange(e)} autocomplete="email" />
|
||||
<Form.Control type="text" placeholder={this.props.user.mail} value={this.state.mail} onChange={(e) => this.handleChange(e)} autoComplete="email" />
|
||||
</Form.Group>
|
||||
<Form.Group as={Col} controlId="oldPassword">
|
||||
<Form.Label>Old Password</Form.Label>
|
||||
<Form.Control type="password" placeholder="Enter current password" value={this.state.oldPassword} onChange={(e) => this.handleChange(e)} autocomplete="current-password" />
|
||||
<Form.Control type="password" placeholder="Enter current password" value={this.state.oldPassword} onChange={(e) => this.handleChange(e)} autoComplete="current-password" />
|
||||
</Form.Group>
|
||||
<Form.Group as={Col} controlId="password">
|
||||
<Form.Label>New Password</Form.Label>
|
||||
<Form.Control type="password" placeholder="Enter new password" value={this.state.password} onChange={(e) => this.handleChange(e)} autocomplete="new-password" />
|
||||
<Form.Control type="password" placeholder="Enter new password" value={this.state.password} onChange={(e) => this.handleChange(e)} autoComplete="new-password" />
|
||||
</Form.Group>
|
||||
<Form.Group as={Col} controlId="confirmPassword">
|
||||
<Form.Label>Confirm New Password</Form.Label>
|
||||
<Form.Control type="password" placeholder="Repeat new password" value={this.state.confirmPassword} onChange={(e) => this.handleChange(e)} autocomplete="new-password" />
|
||||
<Form.Control type="password" placeholder="Repeat new password" value={this.state.confirmPassword} onChange={(e) => this.handleChange(e)} autoComplete="new-password" />
|
||||
</Form.Group>
|
||||
</Form>
|
||||
</Dialog>
|
||||
|
|
|
@ -77,6 +77,9 @@ class EditUserDialog extends React.Component {
|
|||
username: this.props.user.username,
|
||||
mail: this.props.user.mail,
|
||||
role: this.props.user.role,
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
oldPassword: "",
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -66,11 +66,14 @@ class LoginStore extends ReduceStore {
|
|||
return Object.assign({}, state, { token: null, currentUser: null, loginMessage: null});
|
||||
|
||||
case 'users/logged-in':
|
||||
// save login in local storage
|
||||
localStorage.setItem('token', action.token);
|
||||
// save login data in local storage and loginStore
|
||||
let newState = state
|
||||
if (action.token != null){
|
||||
localStorage.setItem('token', action.token);
|
||||
newState = Object.assign({}, state, {token: action.token})
|
||||
}
|
||||
localStorage.setItem('currentUser', JSON.stringify(action.currentUser));
|
||||
|
||||
return Object.assign({}, state, { token: action.token, currentUser: action.currentUser});
|
||||
return Object.assign({}, newState, { currentUser: action.currentUser});
|
||||
|
||||
case 'users/login-error':
|
||||
if (action.error && !action.error.handled) {
|
||||
|
|
128
src/user/user.js
128
src/user/user.js
|
@ -15,100 +15,74 @@
|
|||
* along with VILLASweb. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { Container } from 'flux/utils';
|
||||
import { Button, Form, Row, Col } from 'react-bootstrap';
|
||||
|
||||
import { Form, Row, Col } from 'react-bootstrap';
|
||||
import AppDispatcher from '../common/app-dispatcher';
|
||||
import UsersStore from './users-store';
|
||||
|
||||
import Icon from '../common/icon';
|
||||
import EditOwnUserDialog from './edit-own-user'
|
||||
import NotificationsDataManager from "../common/data-managers/notifications-data-manager"
|
||||
import NotificationsFactory from "../common/data-managers/notifications-factory";
|
||||
import IconButton from "../common/icon-button";
|
||||
import LoginStore from './login-store'
|
||||
|
||||
class User extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
token: LoginStore.getState().token,
|
||||
editModal: false,
|
||||
}
|
||||
}
|
||||
|
||||
class User extends Component {
|
||||
static getStores() {
|
||||
return [ UsersStore ];
|
||||
return [ LoginStore ];
|
||||
}
|
||||
|
||||
static calculateState(prevState, props) {
|
||||
prevState = prevState || {};
|
||||
|
||||
let currentUserID = JSON.parse(localStorage.getItem("currentUser")).id;
|
||||
let currentUser = UsersStore.getState().find(user => user.id === parseInt(currentUserID, 10));
|
||||
|
||||
return {
|
||||
currentUser,
|
||||
token: localStorage.getItem("token"),
|
||||
editModal: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let currentUserID = JSON.parse(localStorage.getItem("currentUser")).id;
|
||||
|
||||
AppDispatcher.dispatch({
|
||||
type: 'users/start-load',
|
||||
data: parseInt(currentUserID, 10),
|
||||
token: this.state.token
|
||||
});
|
||||
currentUser: LoginStore.getState().currentUser
|
||||
}
|
||||
}
|
||||
|
||||
closeEditModal(data) {
|
||||
this.setState({ editModal: false });
|
||||
|
||||
let updatedData = {}
|
||||
let updatedUser = this.state.currentUser;
|
||||
let hasChanged = false;
|
||||
let pwChanged = false;
|
||||
|
||||
updatedData.id = this.state.currentUser.id;
|
||||
|
||||
if (data) {
|
||||
if (data.username !== this.state.currentUser.username) {
|
||||
hasChanged = true;
|
||||
updatedData.username = data.username;
|
||||
updatedUser.username = data.username
|
||||
}
|
||||
|
||||
if (data.mail !== this.state.currentUser.mail) {
|
||||
hasChanged = true;
|
||||
updatedData.mail = data.mail;
|
||||
updatedUser.mail = data.mail;
|
||||
}
|
||||
|
||||
if (data.password !== '' && data.oldPassword !== '' && data.password === data.confirmPassword ) {
|
||||
pwChanged = true;
|
||||
updatedData.password = data.password;
|
||||
updatedData.oldPassword = data.oldPassword;
|
||||
} else if (data.password !== '' && data.password !== data.confirmPassword) {
|
||||
NotificationsDataManager.addNotification(NotificationsFactory.UPDATE_ERROR('New password not correctly confirmed'));
|
||||
return
|
||||
}
|
||||
|
||||
if (hasChanged || pwChanged) {
|
||||
if (hasChanged){
|
||||
this.setState({ currentUser: updatedUser })
|
||||
}
|
||||
|
||||
AppDispatcher.dispatch({
|
||||
type: 'users/start-edit',
|
||||
data: updatedData,
|
||||
token: this.state.token
|
||||
});
|
||||
} else {
|
||||
NotificationsDataManager.addNotification(NotificationsFactory.UPDATE_WARNING('No update requested, no input data'));
|
||||
}
|
||||
AppDispatcher.dispatch({
|
||||
type: 'users/start-edit',
|
||||
data: data,
|
||||
token: this.state.token,
|
||||
currentUser: this.state.currentUser,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let user = this.state.currentUser;
|
||||
|
||||
const buttonStyle = {
|
||||
marginLeft: '10px',
|
||||
}
|
||||
|
||||
const iconStyle = {
|
||||
height: '30px',
|
||||
width: '30px'
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>Account</h1>
|
||||
<h1>Account
|
||||
<span className='icon-button'>
|
||||
|
||||
<IconButton
|
||||
childKey={0}
|
||||
tooltip='Edit Account'
|
||||
onClick={() => this.setState({ editModal: true })}
|
||||
icon='edit'
|
||||
buttonStyle={buttonStyle}
|
||||
iconStyle={iconStyle}
|
||||
/>
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
{user ?
|
||||
<>
|
||||
|
@ -116,30 +90,28 @@ class User extends Component {
|
|||
<Form.Group as={Row} controlId="username">
|
||||
<Form.Label column sm={2}>Username</Form.Label>
|
||||
<Col sm={10}>
|
||||
<Form.Control plaintext readOnly defaultValue={user.username} />
|
||||
<Form.Control plaintext readOnly value={user.username} />
|
||||
</Col>
|
||||
</Form.Group>
|
||||
<Form.Group as={Row} controlId="mail">
|
||||
<Form.Label column sm={2}>E-mail</Form.Label>
|
||||
<Col sm={10}>
|
||||
<Form.Control plaintext readOnly defaultValue={user.mail} type="email" />
|
||||
<Form.Control plaintext readOnly value={user.mail} type="email" />
|
||||
</Col>
|
||||
</Form.Group>
|
||||
<Form.Group as={Row} controlId="role">
|
||||
<Form.Label column sm={2}>Role</Form.Label>
|
||||
<Col sm={10}>
|
||||
<Form.Control plaintext readOnly defaultValue={user.role} />
|
||||
<Form.Control plaintext readOnly value={user.role} />
|
||||
</Col>
|
||||
</Form.Group>
|
||||
<Form.Group as={Row} controlId="formBasicEmail">
|
||||
<Form.Label column sm={2}>Created at</Form.Label>
|
||||
<Col sm={10}>
|
||||
<Form.Control plaintext readOnly defaultValue={user.createdAt} />
|
||||
<Form.Control plaintext readOnly value={user.createdAt} />
|
||||
</Col>
|
||||
</Form.Group>
|
||||
<Button variant="primary" onClick={() => this.setState({ editModal: true })}>
|
||||
<Icon icon='edit' /> Edit
|
||||
</Button>
|
||||
|
||||
</Form>
|
||||
|
||||
<EditOwnUserDialog
|
||||
|
|
|
@ -19,10 +19,13 @@ import ArrayStore from '../common/array-store';
|
|||
import UsersDataManager from './users-data-manager';
|
||||
import NotificationsDataManager from '../common/data-managers/notifications-data-manager';
|
||||
import NotificationsFactory from "../common/data-managers/notifications-factory";
|
||||
import AppDispatcher from "../common/app-dispatcher";
|
||||
|
||||
class UsersStore extends ArrayStore {
|
||||
constructor() {
|
||||
super('users', UsersDataManager);
|
||||
|
||||
this.currentUser = null;
|
||||
}
|
||||
|
||||
reduce(state, action) {
|
||||
|
@ -46,6 +49,33 @@ class UsersStore extends ArrayStore {
|
|||
}
|
||||
return super.reduce(state, action);
|
||||
|
||||
case this.type + '/start-edit':
|
||||
|
||||
// save current user on user edit
|
||||
this.currentUser = action.currentUser;
|
||||
return super.reduce(state, action)
|
||||
|
||||
case this.type + '/edited':
|
||||
|
||||
let currentUserID = this.currentUser.id;
|
||||
|
||||
// check if own user was updated
|
||||
for (let u of [action.data]){
|
||||
if (u.id === currentUserID){
|
||||
console.log("Detected update of current user, updating login store")
|
||||
|
||||
AppDispatcher.dispatch({
|
||||
type: 'users/logged-in',
|
||||
token: null,
|
||||
currentUser: u,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return super.reduce(state, action)
|
||||
|
||||
|
||||
default:
|
||||
return super.reduce(state, action);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import { Container } from 'flux/utils';
|
|||
|
||||
import AppDispatcher from '../common/app-dispatcher';
|
||||
import UsersStore from './users-store';
|
||||
import LoginStore from './login-store';
|
||||
import ScenarioStore from '../scenario/scenario-store';
|
||||
|
||||
import Icon from '../common/icon';
|
||||
|
@ -37,7 +38,7 @@ import NotificationsFactory from "../common/data-managers/notifications-factory"
|
|||
|
||||
class Users extends Component {
|
||||
static getStores() {
|
||||
return [UsersStore, ScenarioStore];
|
||||
return [UsersStore, ScenarioStore, LoginStore];
|
||||
}
|
||||
|
||||
static calculateState(prevState, props) {
|
||||
|
@ -110,7 +111,8 @@ class Users extends Component {
|
|||
AppDispatcher.dispatch({
|
||||
type: 'users/start-edit',
|
||||
data: data,
|
||||
token: this.state.token
|
||||
token: this.state.token,
|
||||
currentUser: this.state.currentUser,
|
||||
});
|
||||
} else {
|
||||
NotificationsDataManager.addNotification(NotificationsFactory.UPDATE_ERROR("New password not correctly confirmed"))
|
||||
|
|
Loading…
Add table
Reference in a new issue