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

View File

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