Migrate ClientStore to mobx

This commit is contained in:
Jannis Mattheis 2018-10-21 13:22:56 +02:00
parent 2871e22a61
commit 3a29ee9305
3 changed files with 49 additions and 99 deletions

View File

@ -1,36 +0,0 @@
import axios, {AxiosResponse} from 'axios';
import * as config from '../config';
import dispatcher from '../stores/dispatcher';
import {snack} from './GlobalAction';
/** Fetches all clients. */
export function fetchClients() {
axios.get(config.get('url') + 'client').then((resp: AxiosResponse<IClient[]>) => {
dispatcher.dispatch({
type: 'UPDATE_CLIENTS',
payload: resp.data,
});
});
}
/**
* Delete a client by id.
* @param {int} id the client id
*/
export function deleteClient(id: number) {
axios
.delete(config.get('url') + 'client/' + id)
.then(fetchClients)
.then(() => snack('Client deleted'));
}
/**
* Create a client.
* @param {string} name the client name
*/
export function createClient(name: string) {
axios
.post(config.get('url') + 'client', {name})
.then(fetchClients)
.then(() => snack('Client created'));
}

View File

@ -8,39 +8,33 @@ import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow'; import TableRow from '@material-ui/core/TableRow';
import Delete from '@material-ui/icons/Delete'; import Delete from '@material-ui/icons/Delete';
import React, {Component, SFC} from 'react'; import React, {Component, SFC} from 'react';
import * as ClientAction from '../actions/ClientAction';
import ConfirmDialog from '../component/ConfirmDialog'; import ConfirmDialog from '../component/ConfirmDialog';
import DefaultPage from '../component/DefaultPage'; import DefaultPage from '../component/DefaultPage';
import ToggleVisibility from '../component/ToggleVisibility'; import ToggleVisibility from '../component/ToggleVisibility';
import ClientStore from '../stores/ClientStore';
import AddClientDialog from './dialog/AddClientDialog'; import AddClientDialog from './dialog/AddClientDialog';
import ClientStore from '../stores/ClientStore';
import {observer} from 'mobx-react';
import {observable} from 'mobx';
interface IState { @observer
clients: IClient[]; class Clients extends Component {
showDialog: boolean; @observable
deleteId: number; private showDialog = false;
} @observable
private deleteId: false | number = false;
class Clients extends Component<{}, IState> { public componentDidMount = ClientStore.refresh;
public state = {clients: [], showDialog: false, deleteId: -1};
public componentWillMount() {
ClientStore.on('change', this.updateClients);
this.updateClients();
}
public componentWillUnmount() {
ClientStore.removeListener('change', this.updateClients);
}
public render() { public render() {
const {clients, deleteId, showDialog} = this.state; const {deleteId, showDialog} = this;
const clients = ClientStore.getItems();
return ( return (
<DefaultPage <DefaultPage
title="Clients" title="Clients"
buttonTitle="Create Client" buttonTitle="Create Client"
buttonId="create-client" buttonId="create-client"
fButton={this.showCreateDialog}> fButton={() => (this.showDialog = true)}>
<Grid item xs={12}> <Grid item xs={12}>
<Paper elevation={6}> <Paper elevation={6}>
<Table id="client-table"> <Table id="client-table">
@ -58,7 +52,7 @@ class Clients extends Component<{}, IState> {
key={client.id} key={client.id}
name={client.name} name={client.name}
value={client.token} value={client.token}
fDelete={() => this.showDeleteDialog(client.id)} fDelete={() => (this.deleteId = client.id)}
/> />
); );
})} })}
@ -68,31 +62,21 @@ class Clients extends Component<{}, IState> {
</Grid> </Grid>
{showDialog && ( {showDialog && (
<AddClientDialog <AddClientDialog
fClose={this.hideCreateDialog} fClose={() => (this.showDialog = false)}
fOnSubmit={ClientAction.createClient} fOnSubmit={ClientStore.create}
/> />
)} )}
{deleteId !== -1 && ( {deleteId !== false && (
<ConfirmDialog <ConfirmDialog
title="Confirm Delete" title="Confirm Delete"
text={'Delete ' + ClientStore.getById(this.state.deleteId).name + '?'} text={'Delete ' + ClientStore.getByID(deleteId).name + '?'}
fClose={this.hideDeleteDelete} fClose={() => (this.deleteId = false)}
fOnSubmit={this.deleteClient} fOnSubmit={() => ClientStore.remove(deleteId)}
/> />
)} )}
</DefaultPage> </DefaultPage>
); );
} }
private deleteClient = () => ClientAction.deleteClient(this.state.deleteId);
private updateClients = () => this.setState({...this.state, clients: ClientStore.get()});
private showCreateDialog = () => this.setState({...this.state, showDialog: true});
private hideCreateDialog = () => this.setState({...this.state, showDialog: false});
private showDeleteDialog = (deleteId: number) => this.setState({...this.state, deleteId});
private hideDeleteDelete = () => this.setState({...this.state, deleteId: -1});
} }
interface IRowProps { interface IRowProps {

View File

@ -1,34 +1,36 @@
import {EventEmitter} from 'events'; import {BaseStore} from './BaseStore';
import {default as dispatcher, IEvent} from './dispatcher'; import axios from 'axios';
import * as config from '../config';
import {action} from 'mobx';
import SnackManager, {SnackReporter} from './SnackManager';
class ClientStore extends EventEmitter { class ClientStore extends BaseStore<IClient> {
private clients: IClient[] = []; public constructor(private readonly snack: SnackReporter) {
super();
public get(): IClient[] {
return this.clients;
} }
public getById(id: number): IClient { protected requestItems = (): Promise<IClient[]> => {
const client = this.clients.find((c) => c.id === id); return axios.get<IClient[]>(`${config.get('url')}client`).then((response) => response.data);
if (!client) { };
throw new Error('client is required to exist');
} protected requestDelete(id: number): Promise<void> {
return client; return axios
.delete(`${config.get('url')}client/${id}`)
.then(() => this.snack('Client deleted'));
} }
public getIdByToken(token: string): number { @action
const client = this.clients.find((c) => c.token === token); public createNoNotifcation = async (name: string): Promise<IClient> => {
return client !== undefined ? client.id : -1; const client = await axios.post(`${config.get('url')}client`, {name});
await this.refresh();
return client.data;
};
@action
public create = async (name: string): Promise<void> => {
await this.createNoNotifcation(name);
this.snack('Client added');
};
} }
public handle(data: IEvent): void { export default new ClientStore(SnackManager.snack);
if (data.type === 'UPDATE_CLIENTS') {
this.clients = data.payload;
this.emit('change');
}
}
}
const store = new ClientStore();
dispatcher.register(store.handle.bind(store));
export default store;