Migrate UserStore to mobx

This commit is contained in:
Jannis Mattheis 2018-10-21 12:46:34 +02:00
parent 9fe00bf004
commit 4107455f89
2 changed files with 57 additions and 68 deletions

View File

@ -10,11 +10,12 @@ import TableRow from '@material-ui/core/TableRow';
import Delete from '@material-ui/icons/Delete'; import Delete from '@material-ui/icons/Delete';
import Edit from '@material-ui/icons/Edit'; import Edit from '@material-ui/icons/Edit';
import React, {Component, SFC} from 'react'; import React, {Component, SFC} from 'react';
import * as UserAction from '../actions/UserAction';
import ConfirmDialog from '../component/ConfirmDialog'; import ConfirmDialog from '../component/ConfirmDialog';
import DefaultPage from '../component/DefaultPage'; import DefaultPage from '../component/DefaultPage';
import UserStore from '../stores/UserStore';
import AddEditDialog from './dialog/AddEditUserDialog'; import AddEditDialog from './dialog/AddEditUserDialog';
import UserStore from '../stores/UserStore';
import {observer} from 'mobx-react';
import {observable} from 'mobx';
const styles = () => ({ const styles = () => ({
wrapper: { wrapper: {
@ -45,33 +46,26 @@ const UserRow: SFC<IRowProps> = ({name, admin, fDelete, fEdit}) => (
</TableRow> </TableRow>
); );
interface IState { @observer
users: IUser[]; class Users extends Component<WithStyles<'wrapper'>> {
createDialog: boolean; @observable
deleteId: number; private createDialog = false;
editId: number; @observable
} private deleteId: number | false = false;
@observable
private editId: number | false = false;
class Users extends Component<WithStyles<'wrapper'>, IState> { public componentDidMount = UserStore.refresh;
public state = {users: [], createDialog: false, deleteId: -1, editId: -1};
public componentWillMount() {
UserStore.on('change', this.updateUsers);
this.updateUsers();
}
public componentWillUnmount() {
UserStore.removeListener('change', this.updateUsers);
}
public render() { public render() {
const {users, deleteId, editId} = this.state; const users = UserStore.getItems();
const {deleteId, editId, createDialog} = this;
return ( return (
<DefaultPage <DefaultPage
title="Users" title="Users"
buttonTitle="Create User" buttonTitle="Create User"
buttonId="create-user" buttonId="create-user"
fButton={this.showCreateDialog}> fButton={() => (this.createDialog = true)}>
<Grid item xs={12}> <Grid item xs={12}>
<Paper elevation={6}> <Paper elevation={6}>
<Table id="user-table"> <Table id="user-table">
@ -89,8 +83,8 @@ class Users extends Component<WithStyles<'wrapper'>, IState> {
key={user.id} key={user.id}
name={user.name} name={user.name}
admin={user.admin} admin={user.admin}
fDelete={() => this.showDeleteDialog(user.id)} fDelete={() => (this.deleteId = user.id)}
fEdit={() => this.showEditDialog(user.id)} fEdit={() => (this.editId = user.id)}
/> />
); );
})} })}
@ -98,43 +92,32 @@ class Users extends Component<WithStyles<'wrapper'>, IState> {
</Table> </Table>
</Paper> </Paper>
</Grid> </Grid>
{this.state.createDialog && ( {createDialog && (
<AddEditDialog <AddEditDialog
fClose={this.hideCreateDialog} fClose={() => (this.createDialog = false)}
fOnSubmit={UserAction.createUser} fOnSubmit={UserStore.create}
/> />
)} )}
{editId !== -1 && ( {editId !== false && (
<AddEditDialog <AddEditDialog
fClose={this.hideEditDialog} fClose={() => (this.editId = false)}
fOnSubmit={UserAction.updateUser.bind(this, editId)} fOnSubmit={UserStore.update.bind(this, editId)}
name={UserStore.getById(this.state.editId).name} name={UserStore.getByID(editId).name}
admin={UserStore.getById(this.state.editId).admin} admin={UserStore.getByID(editId).admin}
isEdit={true} isEdit={true}
/> />
)} )}
{deleteId !== -1 && ( {deleteId !== false && (
<ConfirmDialog <ConfirmDialog
title="Confirm Delete" title="Confirm Delete"
text={'Delete ' + UserStore.getById(this.state.deleteId).name + '?'} text={'Delete ' + UserStore.getByID(deleteId).name + '?'}
fClose={this.hideDeleteDialog} fClose={() => (this.deleteId = false)}
fOnSubmit={() => UserAction.deleteUser(this.state.deleteId)} fOnSubmit={() => UserStore.remove(deleteId)}
/> />
)} )}
</DefaultPage> </DefaultPage>
); );
} }
private updateUsers = () => this.setState({...this.state, users: UserStore.get()});
private showCreateDialog = () => this.setState({...this.state, createDialog: true});
private hideCreateDialog = () => this.setState({...this.state, createDialog: false});
private showEditDialog = (editId: number) => this.setState({...this.state, editId});
private hideEditDialog = () => this.setState({...this.state, editId: -1});
private showDeleteDialog = (deleteId: number) => this.setState({...this.state, deleteId});
private hideDeleteDialog = () => this.setState({...this.state, deleteId: -1});
} }
export default withStyles(styles)(Users); export default withStyles(styles)(Users);

View File

@ -1,29 +1,35 @@
import {EventEmitter} from 'events'; import {BaseStore} from './BaseStore';
import dispatcher, {IEvent} from './dispatcher'; import axios from 'axios';
import * as config from '../config';
import {action} from 'mobx';
import SnackManager, {SnackReporter} from './SnackManager';
class UserStore extends EventEmitter { class UserStore extends BaseStore<IUser> {
private users: IUser[] = []; constructor(private readonly snack: SnackReporter) {
super();
public get(): IUser[] {
return this.users;
} }
public getById(id: number): IUser { protected requestItems = (): Promise<IUser[]> => {
const user = this.users.find((u) => u.id === id); return axios.get<IUser[]>(`${config.get('url')}user`).then((response) => response.data);
if (!user) { };
throw new Error('user must exist');
} protected requestDelete(id: number): Promise<void> {
return user; return axios.delete(`${config.get('url')}user/${id}`).then(() => this.snack("User deleted"));
} }
public handle(data: IEvent): void { @action
if (data.type === 'UPDATE_USERS') { public create = async (name: string, pass: string, admin: boolean) => {
this.users = data.payload; await axios.post(`${config.get('url')}user`, {name, pass, admin});
this.emit('change'); await this.refresh();
} this.snack('User created');
} };
@action
public update = async (id: number, name: string, pass: string | null, admin: boolean) => {
await axios.post(config.get('url') + 'user/' + id, {name, pass, admin});
await this.refresh();
this.snack('User updated');
};
} }
const store = new UserStore(); export default new UserStore(SnackManager.snack);
dispatcher.register(store.handle.bind(store));
export default store;