1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/web/ synced 2025-03-09 00:00:01 +01:00

Clean up usage of login store, only use it for login, use the local storage in all other cases to get the token and current user.

This commit is contained in:
Sonja Happ 2020-09-30 11:29:37 +02:00
parent 34822bb256
commit 4fa2cb13ec
11 changed files with 104 additions and 174 deletions

View file

@ -16,7 +16,6 @@
******************************************************************************/
import React from 'react';
import { Container } from 'flux/utils';
import { DndProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import NotificationSystem from 'react-notification-system';
@ -25,9 +24,6 @@ import { Col } from 'react-bootstrap';
import { Hidden } from 'react-grid-system'
import AppDispatcher from './common/app-dispatcher';
import ScenarioStore from './scenario/scenario-store';
import ICStore from './ic/ic-store';
import LoginStore from './user/login-store';
import NotificationsDataManager from './common/data-managers/notifications-data-manager';
import Home from './common/home';
@ -47,29 +43,21 @@ import './styles/app.css';
class App extends React.Component {
static getStores() {
return [ ICStore, LoginStore, ScenarioStore];
}
static calculateState(prevState) {
return {
ics: ICStore.getState(),
scenarios: ScenarioStore.getState(),
currentUser: LoginStore.getState().currentUser,
token: LoginStore.getState().token,
constructor(props) {
super(props);
this.state = {
showSidebarMenu: false,
};
}
}
componentDidMount() {
NotificationsDataManager.setSystem(this.refs.notificationSystem);
// if token stored locally, request user
// if token stored locally, we are already logged-in
let token = localStorage.getItem("token");
let currentUser = JSON.parse(localStorage.getItem("currentUser"));
if (token != null && token !== '' && currentUser != null) {
if (token != null && token !== '') {
let currentUser = JSON.parse(localStorage.getItem("currentUser"));
console.log("Already logged-in")
AppDispatcher.dispatch({
type: 'users/logged-in',
token: token,
@ -89,13 +77,15 @@ class App extends React.Component {
render() {
let token = localStorage.getItem("token");
let currentUser = JSON.parse(localStorage.getItem("currentUser"));
let currentUserRaw = localStorage.getItem("currentUser");
if (token == null || currentUser == null) {
if (token == null || token === "" || currentUserRaw == null || currentUserRaw === "") {
console.log("APP redirecting to logout/ login")
return (<Redirect to="/logout" />);
}
let currentUser = JSON.parse(currentUserRaw);
return (
<DndProvider backend={HTML5Backend} >
<div>
@ -138,6 +128,5 @@ class App extends React.Component {
}
}
let fluxContainerConverter = require('./common/FluxContainerConverter');
export default Container.create(fluxContainerConverter.convert(App));
//DragDropContext(HTML5Backend)(Container.create(App));
export default App

View file

@ -18,15 +18,12 @@
import React from 'react';
import config from '../config';
import LoginStore from "../user/login-store";
import {Redirect} from "react-router-dom";
class Home extends React.Component {
constructor(props) {
super(props);
// create url for API documentation, distinguish between localhost and production deployment
let docs_url = "";
let docs_location = "/swagger/index.html";
@ -39,8 +36,6 @@ class Home extends React.Component {
}
this.state = {
currentUser: LoginStore.getState().currentUser,
token: LoginStore.getState().token,
docs_url: docs_url
};

View file

@ -43,13 +43,12 @@ import EditConfigDialog from "../componentconfig/edit-config";
import EditSignalMapping from "../signal/edit-signal-mapping";
import FileStore from "../file/file-store"
import WidgetStore from "../widget/widget-store";
import LoginStore from "../user/login-store"
import { Redirect } from 'react-router-dom';
class Scenario extends React.Component {
static getStores() {
return [ ScenarioStore, ConfigStore, DashboardStore, ICStore, SignalStore, FileStore, WidgetStore, LoginStore];
return [ ScenarioStore, ConfigStore, DashboardStore, ICStore, SignalStore, FileStore, WidgetStore];
}
static calculateState(prevState, props) {
@ -68,8 +67,6 @@ class Scenario extends React.Component {
});
}
// obtain all dashboards of a scenario
let dashboards = DashboardStore.getState().filter(dashb => dashb.scenarioID === parseInt(props.match.params.scenario, 10));
// obtain all component configurations of a scenario
let configs = ConfigStore.getState().filter(config => config.scenarioID === parseInt(props.match.params.scenario, 10));
@ -84,24 +81,18 @@ class Scenario extends React.Component {
modalConfigIndex = index;
}
// obtain all files of a scenario
let files = FileStore.getState().filter(file => file.scenarioID === parseInt(props.match.params.scenario, 10));
let signals = SignalStore.getState();
let currentUser = LoginStore.getState().currentUser;
return {
scenario,
sessionToken,
configs,
dashboards,
signals,
currentUser,
files,
editConfigModal,
modalConfigData,
modalConfigIndex,
dashboards: DashboardStore.getState().filter(dashb => dashb.scenarioID === parseInt(props.match.params.scenario, 10)),
signals: SignalStore.getState(),
currentUser: JSON.parse(localStorage.getItem("currentUser")),
files: FileStore.getState().filter(file => file.scenarioID === parseInt(props.match.params.scenario, 10)),
ics: ICStore.getState(),
deleteConfigModal: false,
@ -171,7 +162,7 @@ class Scenario extends React.Component {
closeDeleteUserModal() {
let scenarioID = this.state.scenario.id;
if (this.state.deleteUserName === this.state.currentUser.username) {
if (this.state.deleteUserName === this.state.currentUser.username) {
AppDispatcher.dispatch({
type: 'scenarios/remove-user',
data: scenarioID,

View file

@ -19,7 +19,6 @@ import React from 'react';
import {FormGroup, FormControl, FormLabel, Col} from 'react-bootstrap';
import Dialog from '../common/dialogs/dialog';
//import LoginStore from './login-store';
class EditOwnUserDialog extends React.Component {

View file

@ -31,7 +31,6 @@ class LoginStore extends ReduceStore {
currentUser: null,
token: null,
loginMessage: null,
scenarioUsers: null
};
}
@ -47,31 +46,16 @@ class LoginStore extends ReduceStore {
//remove token and current user from local storage
localStorage.clear();
// delete user and token
return Object.assign({}, state, { token: null, currentUser: null });
// delete user, token and loginMessage
return Object.assign({}, state, { token: null, currentUser: null, loginMessage: null});
case 'users/logged-in':
// // request logged-in user data
UsersDataManager.getCurrentUser(action.token, action.currentUser.id);
// save login in local storage
localStorage.setItem('token', action.token);
localStorage.setItem('currentUser', JSON.stringify(action.currentUser));
return Object.assign({}, state, { token: action.token, currentUser: action.currentUser});
case 'users/current-user':
// // save logged-in user
return Object.assign({}, state, { currentUser: action.currentUser});
case 'users/start-edit-own-user':
// update the current user
UsersDataManager.updateCurrentUser(action.token, action.data);
return Object.assign({}, state, { token: action.token, currentUser: action.data});
case 'users/reload-current-user':
UsersDataManager.getCurrentUser(action.token, action.currentUser.id);
return Object.assign({}, state, { token: action.token, currentUser: action.currentUser});
case 'users/current-user-error':
// discard user token
return Object.assign({}, state, { currentUser: null, token: null });
case 'users/login-error':
if (action.error && !action.error.handled) {
// If it was an error and hasn't been handled, the credentials must have been wrong.

View file

@ -25,54 +25,31 @@ import LoginForm from './login-form';
import Header from '../common/header';
import Footer from '../common/footer';
import NotificationsDataManager from '../common/data-managers/notifications-data-manager';
import AppDispatcher from '../common/app-dispatcher';
import LoginStore from './login-store';
import LoginStore from './login-store'
class Login extends Component {
static getStores() {
return [ LoginStore ];
static getStores(){
return [LoginStore]
}
static calculateState() {
static calculateState(prevState, props) {
// We need to work with the login store here to trigger the re-render upon state change after login
// Upon successful login, the token and currentUser are stored in the local storage as strings
return {
currentUser: LoginStore.getState().currentUser,
token: LoginStore.getState().token,
loginMessage: LoginStore.getState().loginMessage,
};
token: LoginStore.getState().token,
currentUser: LoginStore.getState().currentUser,
}
}
componentDidMount() {
NotificationsDataManager.setSystem(this.refs.notificationSystem);
}
componentDidUpdate(prevProps: Readonly<P>, prevState: Readonly<S>, snapshot: SS): void {
// if token stored locally, request user
if (this.state.token == null) {
const token = localStorage.getItem('token');
const currentUser = JSON.parse(localStorage.getItem('currentUser'));
if (token != null && token !== '' && currentUser != null && this.state.currentUser == null) {
AppDispatcher.dispatch({
type: 'users/logged-in',
token: token,
currentUser: currentUser
});
}
} else {
// check if logged in
if (this.state.currentUser != null) {
// save login in local storage
localStorage.setItem('token', this.state.token);
localStorage.setItem('currentUser', JSON.stringify(this.state.currentUser));
}
}
}
render() {
if (this.state.currentUser != null) {
if (this.state.currentUser !== null && this.state.currentUser !== "") {
return (<Redirect to="/home" />);
}

View file

@ -26,8 +26,11 @@ class Logout extends React.Component {
type: 'users/logout'
});
// discard login token
// The Login Store is deleted automatically
// discard login token and current User
localStorage.setItem('token', '');
localStorage.setItem('currentUser', '');
}
render() {

View file

@ -26,7 +26,6 @@ import Icon from '../common/icon';
import EditOwnUserDialog from './edit-own-user'
import NotificationsDataManager from "../common/data-managers/notifications-data-manager"
class User extends Component {
static getStores() {
return [ UsersStore ];
@ -35,32 +34,52 @@ class User extends Component {
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: JSON.parse(localStorage.getItem("currentUser")),
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
});
}
closeEditModal(data) {
this.setState({ editModal: false });
//this.setState({currentUser: data});
let updatedData = {};
let updatedData = {}
updatedData.id = this.state.currentUser.id;
let updatedUser = this.state.currentUser;
let hasChanged = false;
let pwChanged = false;
if(data){
if (data.username !== ''){
updatedData["id"] = data.id;
updatedData["username"] = data.username;
hasChanged = true;
updatedData.username = data.username;
updatedUser.username = data.username
}
if (data.mail !== ''){
updatedData["id"] = data.id;
updatedData["mail"] = data.mail;
hasChanged = true;
updatedData.mail = data.mail;
updatedUser.mail = data.mail;
}
if (data.password !== '' && data.oldPassword !== '' && data.password === data.confirmpassword ){
updatedData["id"] = data.id;
updatedData["password"] = data.password;
updatedData["oldPassword"] = data.oldPassword;
pwChanged = true;
updatedData.password = data.password;
updatedData.oldPassword = data.oldPassword;
} else if (data.password !== '' && data.password !== data.confirmpassword) {
const USER_UPDATE_ERROR_NOTIFICATION = {
title: 'Update Error ',
@ -71,13 +90,15 @@ class User extends Component {
return
}
if (updatedData !== {}) {
let requestData = {};
requestData["user"] = updatedData;
if (hasChanged || pwChanged) {
if(hasChanged){
this.setState({currentUser: updatedUser})
}
AppDispatcher.dispatch({
type: 'users/start-edit-own-user',
data: requestData,
type: 'users/start-edit',
data: updatedData,
token: this.state.token
});
} else {
@ -100,35 +121,37 @@ class User extends Component {
render() {
return (
<div>
<h1>Your User Account</h1>
<form>
<Row>
<Col xs={3}>Username: </Col>
<Col xs={3}> {this.state.currentUser.username} </Col>
</Row>
{this.state.currentUser !== undefined && this.state.currentUser !== null ?
<form>
<Row>
<Col xs={3}>Username: </Col>
<Col xs={3}> {this.state.currentUser.username} </Col>
</Row>
<Row as={Col} >
<Col xs={3}>E-mail: </Col>
<Col xs={3}> {this.state.currentUser.mail} </Col>
</Row>
<Row as={Col}>
<Col xs={3}>E-mail: </Col>
<Col xs={3}> {this.state.currentUser.mail} </Col>
</Row>
<Row as={Col} >
<Col xs={3}>Role: </Col>
<Col xs={3}> {this.state.currentUser.role} </Col>
</Row>
<Row as={Col}>
<Col xs={3}>Role: </Col>
<Col xs={3}> {this.state.currentUser.role} </Col>
</Row>
<Button onClick={() => this.setState({ editModal: true })}><Icon icon='edit' /> Edit</Button>
<Button onClick={() => this.setState({editModal: true})}><Icon icon='edit'/> Edit</Button>
<EditOwnUserDialog show={this.state.editModal} onClose={(data) => this.closeEditModal(data)} user={this.state.currentUser} />
</form>
<EditOwnUserDialog show={this.state.editModal} onClose={(data) => this.closeEditModal(data)}
user={this.state.currentUser}/>
</form> : "Loading user data..."
}
</div>
);
}

View file

@ -38,35 +38,6 @@ class UsersDataManager extends RestDataManager {
});
});
}
getCurrentUser(token, id) {
RestAPI.get(this.makeURL('/users/' + id), token).then(response => {
AppDispatcher.dispatch({
type: 'users/current-user',
currentUser: response.user
});
}).catch(error => {
AppDispatcher.dispatch({
type: 'users/current-user-error',
error: error
});
});
}
updateCurrentUser(token, userUpdate){
RestAPI.put(this.makeURL('/users/' + userUpdate.user.id), userUpdate, token).then( response => {
AppDispatcher.dispatch({
type: 'users/current-user',
currentUser: response.user
});
}).catch(error => {
AppDispatcher.dispatch({
type: 'users/current-user-error',
error: error
});
});
}
}
export default new UsersDataManager();

View file

@ -19,7 +19,6 @@ import React from 'react';
import { Container } from 'flux/utils';
import AppDispatcher from '../common/app-dispatcher';
import LoginStore from '../user/login-store';
import ICDataStore from '../ic/ic-data-store';
import ConfigsStore from '../componentconfig/config-store';
import FileStore from '../file/file-store';
@ -49,7 +48,7 @@ import '../styles/widgets.css';
class Widget extends React.Component {
static getStores() {
return [ ICDataStore, ConfigsStore, FileStore, LoginStore, SignalStore];
return [ ICDataStore, ConfigsStore, FileStore, SignalStore];
}
static calculateState(prevState, props) {
@ -85,7 +84,7 @@ class Widget extends React.Component {
signals: signals,
icIDs: icIDs,
files: FileStore.getState(),
sessionToken: LoginStore.getState().token
sessionToken: localStorage.getItem("token")
};
}

View file

@ -18,7 +18,6 @@
import React, { Component } from 'react';
import { Button } from 'react-bootstrap';
import Icon from '../../common/icon';
import LoginStore from '../../user/login-store';
import ICStore from '../../ic/ic-store';
import AppDispatcher from '../../common/app-dispatcher';
@ -32,7 +31,7 @@ class WidgetCustomAction extends Component {
}
static getStores() {
return [ ICStore, LoginStore ];
return [ ICStore ];
}
static getDerivedStateFromProps(props, state){
@ -42,7 +41,7 @@ class WidgetCustomAction extends Component {
return{
ic: ICStore.getState().find(s => s.id === props.icIDs[0]),
sessionToken: LoginStore.getState().token
sessionToken: localStorage.getItem("token")
};
}