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

View File

@ -1,34 +1,36 @@
import {EventEmitter} from 'events';
import {default as 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 ClientStore extends EventEmitter {
private clients: IClient[] = [];
public get(): IClient[] {
return this.clients;
class ClientStore extends BaseStore<IClient> {
public constructor(private readonly snack: SnackReporter) {
super();
}
public getById(id: number): IClient {
const client = this.clients.find((c) => c.id === id);
if (!client) {
throw new Error('client is required to exist');
}
return client;
protected requestItems = (): Promise<IClient[]> => {
return axios.get<IClient[]>(`${config.get('url')}client`).then((response) => response.data);
};
protected requestDelete(id: number): Promise<void> {
return axios
.delete(`${config.get('url')}client/${id}`)
.then(() => this.snack('Client deleted'));
}
public getIdByToken(token: string): number {
const client = this.clients.find((c) => c.token === token);
return client !== undefined ? client.id : -1;
@action
public createNoNotifcation = async (name: string): Promise<IClient> => {
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 {
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;
export default new ClientStore(SnackManager.snack);