Use inject everywhere
This commit is contained in:
parent
bbb344be72
commit
d8c413df03
|
|
@ -15,9 +15,9 @@ import Clients from './pages/Clients';
|
||||||
import Login from './pages/Login';
|
import Login from './pages/Login';
|
||||||
import Messages from './pages/Messages';
|
import Messages from './pages/Messages';
|
||||||
import Users from './pages/Users';
|
import Users from './pages/Users';
|
||||||
import {currentUser} from './stores/CurrentUser';
|
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
import {observable} from 'mobx';
|
import {observable} from 'mobx';
|
||||||
|
import {inject, Stores} from './inject';
|
||||||
|
|
||||||
const lightTheme = createMuiTheme({
|
const lightTheme = createMuiTheme({
|
||||||
palette: {
|
palette: {
|
||||||
|
|
@ -40,7 +40,7 @@ const styles = (theme: Theme) => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Layout extends React.Component<WithStyles<'content'>> {
|
class Layout extends React.Component<WithStyles<'content'> & Stores<'currentUser'>> {
|
||||||
private static defaultVersion = '0.0.0';
|
private static defaultVersion = '0.0.0';
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
|
|
@ -59,14 +59,16 @@ class Layout extends React.Component<WithStyles<'content'>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
|
const {version, showSettings, darkThemeVisible} = this;
|
||||||
const {
|
const {
|
||||||
|
classes,
|
||||||
|
currentUser: {
|
||||||
loggedIn,
|
loggedIn,
|
||||||
authenticating,
|
authenticating,
|
||||||
user: {name, admin},
|
user: {name, admin},
|
||||||
} = currentUser;
|
logout,
|
||||||
|
},
|
||||||
const {version, showSettings, darkThemeVisible} = this;
|
} = this.props;
|
||||||
const {classes} = this.props;
|
|
||||||
const theme = darkThemeVisible ? darkTheme : lightTheme;
|
const theme = darkThemeVisible ? darkTheme : lightTheme;
|
||||||
const loginRoute = () => (loggedIn ? <Redirect to="/" /> : <Login />);
|
const loginRoute = () => (loggedIn ? <Redirect to="/" /> : <Login />);
|
||||||
return (
|
return (
|
||||||
|
|
@ -81,6 +83,7 @@ class Layout extends React.Component<WithStyles<'content'>> {
|
||||||
loggedIn={loggedIn}
|
loggedIn={loggedIn}
|
||||||
toggleTheme={() => (this.darkThemeVisible = !this.darkThemeVisible)}
|
toggleTheme={() => (this.darkThemeVisible = !this.darkThemeVisible)}
|
||||||
showSettings={() => (this.showSettings = true)}
|
showSettings={() => (this.showSettings = true)}
|
||||||
|
logout={logout}
|
||||||
/>
|
/>
|
||||||
<Navigation loggedIn={loggedIn} />
|
<Navigation loggedIn={loggedIn} />
|
||||||
|
|
||||||
|
|
@ -112,4 +115,4 @@ class Layout extends React.Component<WithStyles<'content'>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withStyles(styles, {withTheme: true})<{}>(Layout);
|
export default withStyles(styles, {withTheme: true})<{}>(inject('currentUser')(Layout));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
import axios from 'axios';
|
||||||
|
import {CurrentUser} from '../stores/CurrentUser';
|
||||||
|
import {SnackReporter} from '../stores/SnackManager';
|
||||||
|
|
||||||
|
export const initAxios = (currentUser: CurrentUser, snack: SnackReporter) => {
|
||||||
|
axios.interceptors.request.use((config) => {
|
||||||
|
config.headers['X-Gotify-Key'] = currentUser.token();
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
|
||||||
|
axios.interceptors.response.use(undefined, (error) => {
|
||||||
|
if (!error.response) {
|
||||||
|
snack('Gotify server is not reachable, try refreshing the page.');
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const status = error.response.status;
|
||||||
|
|
||||||
|
if (status === 401) {
|
||||||
|
currentUser.tryAuthenticate().then(() => snack('Could not complete request.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 400) {
|
||||||
|
snack(error.response.data.error + ': ' + error.response.data.errorDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
import axios from 'axios';
|
|
||||||
import {currentUser} from '../stores/CurrentUser';
|
|
||||||
import SnackManager from '../stores/SnackManager';
|
|
||||||
|
|
||||||
axios.interceptors.request.use((config) => {
|
|
||||||
config.headers['X-Gotify-Key'] = currentUser.token();
|
|
||||||
return config;
|
|
||||||
});
|
|
||||||
|
|
||||||
axios.interceptors.response.use(undefined, (error) => {
|
|
||||||
if (!error.response) {
|
|
||||||
SnackManager.snack('Gotify server is not reachable, try refreshing the page.');
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
const status = error.response.status;
|
|
||||||
|
|
||||||
if (status === 401) {
|
|
||||||
currentUser.tryAuthenticate().then(() => SnackManager.snack('Could not complete request.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 400) {
|
|
||||||
SnackManager.snack(error.response.data.error + ': ' + error.response.data.errorDescription);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.reject(error);
|
|
||||||
});
|
|
||||||
|
|
@ -12,7 +12,6 @@ import Highlight from '@material-ui/icons/Highlight';
|
||||||
import SupervisorAccount from '@material-ui/icons/SupervisorAccount';
|
import SupervisorAccount from '@material-ui/icons/SupervisorAccount';
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {Link} from 'react-router-dom';
|
import {Link} from 'react-router-dom';
|
||||||
import {currentUser} from '../stores/CurrentUser';
|
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
|
|
||||||
const styles = (theme: Theme) => ({
|
const styles = (theme: Theme) => ({
|
||||||
|
|
@ -42,12 +41,13 @@ interface IProps {
|
||||||
version: string;
|
version: string;
|
||||||
toggleTheme: VoidFunction;
|
toggleTheme: VoidFunction;
|
||||||
showSettings: VoidFunction;
|
showSettings: VoidFunction;
|
||||||
|
logout: VoidFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Header extends Component<IProps & Styles> {
|
class Header extends Component<IProps & Styles> {
|
||||||
public render() {
|
public render() {
|
||||||
const {classes, version, name, loggedIn, admin, toggleTheme} = this.props;
|
const {classes, version, name, loggedIn, admin, toggleTheme, logout} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppBar position="absolute" className={classes.appBar}>
|
<AppBar position="absolute" className={classes.appBar}>
|
||||||
|
|
@ -69,7 +69,7 @@ class Header extends Component<IProps & Styles> {
|
||||||
</Typography>
|
</Typography>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{loggedIn && this.renderButtons(name, admin)}
|
{loggedIn && this.renderButtons(name, admin, logout)}
|
||||||
<IconButton onClick={toggleTheme} color="inherit">
|
<IconButton onClick={toggleTheme} color="inherit">
|
||||||
<Highlight />
|
<Highlight />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
@ -78,7 +78,7 @@ class Header extends Component<IProps & Styles> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderButtons(name: string, admin: boolean) {
|
private renderButtons(name: string, admin: boolean, logout: VoidFunction) {
|
||||||
const {classes, showSettings} = this.props;
|
const {classes, showSettings} = this.props;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -109,7 +109,7 @@ class Header extends Component<IProps & Styles> {
|
||||||
|
|
||||||
{name}
|
{name}
|
||||||
</Button>
|
</Button>
|
||||||
<Button color="inherit" onClick={currentUser.logout} id="logout">
|
<Button color="inherit" onClick={logout} id="logout">
|
||||||
<ExitToApp />
|
<ExitToApp />
|
||||||
Logout
|
Logout
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import ListItemText from '@material-ui/core/ListItemText';
|
||||||
import {StyleRules, Theme, WithStyles, withStyles} from '@material-ui/core/styles';
|
import {StyleRules, Theme, WithStyles, withStyles} from '@material-ui/core/styles';
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {Link} from 'react-router-dom';
|
import {Link} from 'react-router-dom';
|
||||||
import AppStore from '../stores/AppStore';
|
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
|
import {inject, Stores} from '../inject';
|
||||||
|
|
||||||
const styles = (theme: Theme): StyleRules<'drawerPaper' | 'toolbar' | 'link'> => ({
|
const styles = (theme: Theme): StyleRules<'drawerPaper' | 'toolbar' | 'link'> => ({
|
||||||
drawerPaper: {
|
drawerPaper: {
|
||||||
|
|
@ -29,10 +29,10 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Navigation extends Component<IProps & Styles> {
|
class Navigation extends Component<IProps & Styles & Stores<'appStore'>> {
|
||||||
public render() {
|
public render() {
|
||||||
const {classes, loggedIn} = this.props;
|
const {classes, loggedIn, appStore} = this.props;
|
||||||
const apps = AppStore.getItems();
|
const apps = appStore.getItems();
|
||||||
|
|
||||||
const userApps =
|
const userApps =
|
||||||
apps.length === 0
|
apps.length === 0
|
||||||
|
|
@ -78,4 +78,4 @@ class Navigation extends Component<IProps & Styles> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withStyles(styles, {withTheme: true})<IProps>(Navigation);
|
export default withStyles(styles, {withTheme: true})<IProps>(inject('appStore')(Navigation));
|
||||||
|
|
|
||||||
|
|
@ -6,22 +6,22 @@ import DialogTitle from '@material-ui/core/DialogTitle';
|
||||||
import TextField from '@material-ui/core/TextField';
|
import TextField from '@material-ui/core/TextField';
|
||||||
import Tooltip from '@material-ui/core/Tooltip';
|
import Tooltip from '@material-ui/core/Tooltip';
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {currentUser} from '../stores/CurrentUser';
|
|
||||||
import {observable} from 'mobx';
|
import {observable} from 'mobx';
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
|
import {inject, Stores} from '../inject';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
fClose: VoidFunction;
|
fClose: VoidFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export default class SettingsDialog extends Component<IProps> {
|
class SettingsDialog extends Component<IProps & Stores<'currentUser'>> {
|
||||||
@observable
|
@observable
|
||||||
private pass = '';
|
private pass = '';
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {pass} = this;
|
const {pass} = this;
|
||||||
const {fClose} = this.props;
|
const {fClose, currentUser} = this.props;
|
||||||
const submitAndClose = () => {
|
const submitAndClose = () => {
|
||||||
currentUser.changePassword(pass);
|
currentUser.changePassword(pass);
|
||||||
fClose();
|
fClose();
|
||||||
|
|
@ -64,3 +64,5 @@ export default class SettingsDialog extends Component<IProps> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default inject('currentUser')(SettingsDialog);
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ import Close from '@material-ui/icons/Close';
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {observable, reaction} from 'mobx';
|
import {observable, reaction} from 'mobx';
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
import SnackManager from '../stores/SnackManager';
|
import {inject, Stores} from '../inject';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class SnackBarHandler extends Component {
|
class SnackBarHandler extends Component<Stores<'snackManager'>> {
|
||||||
private static MAX_VISIBLE_SNACK_TIME_IN_MS = 6000;
|
private static MAX_VISIBLE_SNACK_TIME_IN_MS = 6000;
|
||||||
private static MIN_VISIBLE_SNACK_TIME_IN_MS = 1000;
|
private static MIN_VISIBLE_SNACK_TIME_IN_MS = 1000;
|
||||||
|
|
||||||
|
|
@ -19,12 +19,12 @@ class SnackBarHandler extends Component {
|
||||||
private dispose: () => void = () => {};
|
private dispose: () => void = () => {};
|
||||||
|
|
||||||
public componentDidMount = () =>
|
public componentDidMount = () =>
|
||||||
(this.dispose = reaction(() => SnackManager.counter, this.onNewSnack));
|
(this.dispose = reaction(() => this.props.snackManager.counter, this.onNewSnack));
|
||||||
|
|
||||||
public componentWillUnmount = () => this.dispose();
|
public componentWillUnmount = () => this.dispose();
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {message: current, hasNext} = SnackManager;
|
const {message: current, hasNext} = this.props.snackManager;
|
||||||
const duration = hasNext()
|
const duration = hasNext()
|
||||||
? SnackBarHandler.MIN_VISIBLE_SNACK_TIME_IN_MS
|
? SnackBarHandler.MIN_VISIBLE_SNACK_TIME_IN_MS
|
||||||
: SnackBarHandler.MAX_VISIBLE_SNACK_TIME_IN_MS;
|
: SnackBarHandler.MAX_VISIBLE_SNACK_TIME_IN_MS;
|
||||||
|
|
@ -70,14 +70,14 @@ class SnackBarHandler extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
private openNextSnack = () => {
|
private openNextSnack = () => {
|
||||||
if (SnackManager.hasNext()) {
|
if (this.props.snackManager.hasNext()) {
|
||||||
this.open = true;
|
this.open = true;
|
||||||
this.openWhen = Date.now();
|
this.openWhen = Date.now();
|
||||||
SnackManager.next();
|
this.props.snackManager.next();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private closeCurrentSnack = () => (this.open = false);
|
private closeCurrentSnack = () => (this.open = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SnackBarHandler;
|
export default inject('snackManager')(SnackBarHandler);
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,20 @@ import * as React from 'react';
|
||||||
import * as ReactDOM from 'react-dom';
|
import * as ReactDOM from 'react-dom';
|
||||||
import 'typeface-roboto';
|
import 'typeface-roboto';
|
||||||
import 'typeface-roboto-mono';
|
import 'typeface-roboto-mono';
|
||||||
import './actions/defaultAxios';
|
import {initAxios} from './actions/axios';
|
||||||
import * as config from './config';
|
import * as config from './config';
|
||||||
import Layout from './Layout';
|
import Layout from './Layout';
|
||||||
import registerServiceWorker from './registerServiceWorker';
|
import registerServiceWorker from './registerServiceWorker';
|
||||||
import * as Notifications from './stores/Notifications';
|
import * as Notifications from './stores/Notifications';
|
||||||
import {currentUser} from './stores/CurrentUser';
|
import {CurrentUser} from './stores/CurrentUser';
|
||||||
import AppStore from './stores/AppStore';
|
import {AppStore} from './stores/AppStore';
|
||||||
import {reaction} from 'mobx';
|
import {reaction} from 'mobx';
|
||||||
import {WebSocketStore} from './stores/WebSocketStore';
|
import {WebSocketStore} from './stores/WebSocketStore';
|
||||||
import SnackManager from './stores/SnackManager';
|
import {SnackManager} from './stores/SnackManager';
|
||||||
|
import {InjectProvider, StoreMapping} from './inject';
|
||||||
|
import {UserStore} from './stores/UserStore';
|
||||||
|
import {MessagesStore} from './stores/MessagesStore';
|
||||||
|
import {ClientStore} from './stores/ClientStore';
|
||||||
|
|
||||||
const defaultDevConfig = {
|
const defaultDevConfig = {
|
||||||
url: 'http://localhost:80/',
|
url: 'http://localhost:80/',
|
||||||
|
|
@ -33,6 +37,26 @@ declare global {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initStores = (): StoreMapping => {
|
||||||
|
const snackManager = new SnackManager();
|
||||||
|
const appStore = new AppStore(snackManager.snack);
|
||||||
|
const userStore = new UserStore(snackManager.snack);
|
||||||
|
const messagesStore = new MessagesStore(appStore, snackManager.snack);
|
||||||
|
const currentUser = new CurrentUser(snackManager.snack);
|
||||||
|
const clientStore = new ClientStore(snackManager.snack);
|
||||||
|
const wsStore = new WebSocketStore(snackManager.snack, currentUser, messagesStore);
|
||||||
|
|
||||||
|
return {
|
||||||
|
appStore,
|
||||||
|
snackManager,
|
||||||
|
userStore,
|
||||||
|
messagesStore,
|
||||||
|
currentUser,
|
||||||
|
clientStore,
|
||||||
|
wsStore,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
(function clientJS() {
|
(function clientJS() {
|
||||||
Notifications.requestPermission();
|
Notifications.requestPermission();
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
|
@ -40,20 +64,28 @@ declare global {
|
||||||
} else {
|
} else {
|
||||||
config.set(window.config || defaultDevConfig);
|
config.set(window.config || defaultDevConfig);
|
||||||
}
|
}
|
||||||
const ws = new WebSocketStore(SnackManager.snack);
|
const stores = initStores();
|
||||||
|
initAxios(stores.currentUser, stores.snackManager.snack);
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
() => currentUser.loggedIn,
|
() => stores.currentUser.loggedIn,
|
||||||
(loggedIn) => {
|
(loggedIn) => {
|
||||||
if (loggedIn) {
|
if (loggedIn) {
|
||||||
ws.listen();
|
stores.wsStore.listen();
|
||||||
} else {
|
} else {
|
||||||
ws.close();
|
stores.wsStore.close();
|
||||||
}
|
}
|
||||||
AppStore.refresh();
|
stores.appStore.refresh();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
currentUser.tryAuthenticate();
|
stores.currentUser.tryAuthenticate();
|
||||||
ReactDOM.render(<Layout />, document.getElementById('root'));
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<InjectProvider stores={stores}>
|
||||||
|
<Layout />
|
||||||
|
</InjectProvider>,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
registerServiceWorker();
|
registerServiceWorker();
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,12 @@ 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 AddApplicationDialog from './dialog/AddApplicationDialog';
|
import AddApplicationDialog from './dialog/AddApplicationDialog';
|
||||||
import AppStore from '../stores/AppStore';
|
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
import {observable} from 'mobx';
|
import {observable} from 'mobx';
|
||||||
|
import {inject, Stores} from '../inject';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Applications extends Component {
|
class Applications extends Component<Stores<'appStore'>> {
|
||||||
@observable
|
@observable
|
||||||
private deleteId: number | false = false;
|
private deleteId: number | false = false;
|
||||||
@observable
|
@observable
|
||||||
|
|
@ -28,11 +28,15 @@ class Applications extends Component {
|
||||||
private uploadId = -1;
|
private uploadId = -1;
|
||||||
private upload: HTMLInputElement | null = null;
|
private upload: HTMLInputElement | null = null;
|
||||||
|
|
||||||
public componentDidMount = AppStore.refresh;
|
public componentDidMount = () => this.props.appStore.refresh();
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {createDialog, deleteId} = this;
|
const {
|
||||||
const apps = AppStore.getItems();
|
createDialog,
|
||||||
|
deleteId,
|
||||||
|
props: {appStore},
|
||||||
|
} = this;
|
||||||
|
const apps = appStore.getItems();
|
||||||
return (
|
return (
|
||||||
<DefaultPage
|
<DefaultPage
|
||||||
title="Applications"
|
title="Applications"
|
||||||
|
|
@ -79,15 +83,15 @@ class Applications extends Component {
|
||||||
{createDialog && (
|
{createDialog && (
|
||||||
<AddApplicationDialog
|
<AddApplicationDialog
|
||||||
fClose={() => (this.createDialog = false)}
|
fClose={() => (this.createDialog = false)}
|
||||||
fOnSubmit={AppStore.create}
|
fOnSubmit={appStore.create}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{deleteId !== false && (
|
{deleteId !== false && (
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title="Confirm Delete"
|
title="Confirm Delete"
|
||||||
text={'Delete ' + AppStore.getByID(deleteId).name + '?'}
|
text={'Delete ' + appStore.getByID(deleteId).name + '?'}
|
||||||
fClose={() => (this.deleteId = false)}
|
fClose={() => (this.deleteId = false)}
|
||||||
fOnSubmit={() => AppStore.remove(deleteId)}
|
fOnSubmit={() => appStore.remove(deleteId)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</DefaultPage>
|
</DefaultPage>
|
||||||
|
|
@ -107,7 +111,7 @@ class Applications extends Component {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (['image/png', 'image/jpeg', 'image/gif'].indexOf(file.type) !== -1) {
|
if (['image/png', 'image/jpeg', 'image/gif'].indexOf(file.type) !== -1) {
|
||||||
AppStore.uploadImage(this.uploadId, file);
|
this.props.appStore.uploadImage(this.uploadId, file);
|
||||||
} else {
|
} else {
|
||||||
alert('Uploaded file must be of type png, jpeg or gif.');
|
alert('Uploaded file must be of type png, jpeg or gif.');
|
||||||
}
|
}
|
||||||
|
|
@ -146,4 +150,4 @@ const Row: SFC<IRowProps> = observer(({name, value, description, fDelete, fUploa
|
||||||
</TableRow>
|
</TableRow>
|
||||||
));
|
));
|
||||||
|
|
||||||
export default Applications;
|
export default inject('appStore')(Applications);
|
||||||
|
|
|
||||||
|
|
@ -12,22 +12,26 @@ 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 AddClientDialog from './dialog/AddClientDialog';
|
import AddClientDialog from './dialog/AddClientDialog';
|
||||||
import ClientStore from '../stores/ClientStore';
|
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
import {observable} from 'mobx';
|
import {observable} from 'mobx';
|
||||||
|
import {inject, Stores} from '../inject';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Clients extends Component {
|
class Clients extends Component<Stores<'clientStore'>> {
|
||||||
@observable
|
@observable
|
||||||
private showDialog = false;
|
private showDialog = false;
|
||||||
@observable
|
@observable
|
||||||
private deleteId: false | number = false;
|
private deleteId: false | number = false;
|
||||||
|
|
||||||
public componentDidMount = ClientStore.refresh;
|
public componentDidMount = () => this.props.clientStore.refresh();
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {deleteId, showDialog} = this;
|
const {
|
||||||
const clients = ClientStore.getItems();
|
deleteId,
|
||||||
|
showDialog,
|
||||||
|
props: {clientStore},
|
||||||
|
} = this;
|
||||||
|
const clients = clientStore.getItems();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DefaultPage
|
<DefaultPage
|
||||||
|
|
@ -63,15 +67,15 @@ class Clients extends Component {
|
||||||
{showDialog && (
|
{showDialog && (
|
||||||
<AddClientDialog
|
<AddClientDialog
|
||||||
fClose={() => (this.showDialog = false)}
|
fClose={() => (this.showDialog = false)}
|
||||||
fOnSubmit={ClientStore.create}
|
fOnSubmit={clientStore.create}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{deleteId !== false && (
|
{deleteId !== false && (
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title="Confirm Delete"
|
title="Confirm Delete"
|
||||||
text={'Delete ' + ClientStore.getByID(deleteId).name + '?'}
|
text={'Delete ' + clientStore.getByID(deleteId).name + '?'}
|
||||||
fClose={() => (this.deleteId = false)}
|
fClose={() => (this.deleteId = false)}
|
||||||
fOnSubmit={() => ClientStore.remove(deleteId)}
|
fOnSubmit={() => clientStore.remove(deleteId)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</DefaultPage>
|
</DefaultPage>
|
||||||
|
|
@ -102,4 +106,4 @@ const Row: SFC<IRowProps> = ({name, value, fDelete}) => (
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Clients;
|
export default inject('clientStore')(Clients);
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ import TextField from '@material-ui/core/TextField';
|
||||||
import React, {Component, FormEvent} from 'react';
|
import React, {Component, FormEvent} from 'react';
|
||||||
import Container from '../component/Container';
|
import Container from '../component/Container';
|
||||||
import DefaultPage from '../component/DefaultPage';
|
import DefaultPage from '../component/DefaultPage';
|
||||||
import {currentUser} from '../stores/CurrentUser';
|
|
||||||
import {observable} from 'mobx';
|
import {observable} from 'mobx';
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
|
import {inject, Stores} from '../inject';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Login extends Component {
|
class Login extends Component<Stores<'currentUser'>> {
|
||||||
@observable
|
@observable
|
||||||
private username = '';
|
private username = '';
|
||||||
@observable
|
@observable
|
||||||
|
|
@ -57,10 +57,10 @@ class Login extends Component {
|
||||||
|
|
||||||
private login = (e: React.MouseEvent<HTMLInputElement>) => {
|
private login = (e: React.MouseEvent<HTMLInputElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
currentUser.login(this.username, this.password);
|
this.props.currentUser.login(this.username, this.password);
|
||||||
};
|
};
|
||||||
|
|
||||||
private preventDefault = (e: FormEvent<HTMLFormElement>) => e.preventDefault();
|
private preventDefault = (e: FormEvent<HTMLFormElement>) => e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Login;
|
export default inject('currentUser')(Login);
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,10 @@ import React, {Component} from 'react';
|
||||||
import {RouteComponentProps} from 'react-router';
|
import {RouteComponentProps} from 'react-router';
|
||||||
import DefaultPage from '../component/DefaultPage';
|
import DefaultPage from '../component/DefaultPage';
|
||||||
import Message from '../component/Message';
|
import Message from '../component/Message';
|
||||||
import AppStore from '../stores/AppStore';
|
|
||||||
import MessagesStore from '../stores/MessagesStore';
|
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import InfiniteAnyHeight from 'react-infinite-any-height';
|
import InfiniteAnyHeight from 'react-infinite-any-height';
|
||||||
|
import {inject, Stores} from '../inject';
|
||||||
|
|
||||||
interface IProps extends RouteComponentProps<{id: string}> {}
|
interface IProps extends RouteComponentProps<{id: string}> {}
|
||||||
|
|
||||||
|
|
@ -18,7 +17,7 @@ interface IState {
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Messages extends Component<IProps, IState> {
|
class Messages extends Component<IProps & Stores<'messagesStore' | 'appStore'>, IState> {
|
||||||
private static appId(props: IProps) {
|
private static appId(props: IProps) {
|
||||||
if (props === undefined) {
|
if (props === undefined) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -31,7 +30,7 @@ class Messages extends Component<IProps, IState> {
|
||||||
|
|
||||||
private isLoadingMore = false;
|
private isLoadingMore = false;
|
||||||
|
|
||||||
public componentWillReceiveProps(nextProps: IProps) {
|
public componentWillReceiveProps(nextProps: IProps & Stores<'messagesStore' | 'appStore'>) {
|
||||||
this.updateAllWithProps(nextProps);
|
this.updateAllWithProps(nextProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,9 +48,10 @@ class Messages extends Component<IProps, IState> {
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {appId} = this.state;
|
const {appId} = this.state;
|
||||||
const messages = MessagesStore.get(appId);
|
const {messagesStore, appStore} = this.props;
|
||||||
const hasMore = MessagesStore.canLoadMore(appId);
|
const messages = messagesStore.get(appId);
|
||||||
const name = AppStore.getName(appId);
|
const hasMore = messagesStore.canLoadMore(appId);
|
||||||
|
const name = appStore.getName(appId);
|
||||||
const hasMessages = messages.length !== 0;
|
const hasMessages = messages.length !== 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -59,7 +59,7 @@ class Messages extends Component<IProps, IState> {
|
||||||
title={name}
|
title={name}
|
||||||
buttonTitle="Delete All"
|
buttonTitle="Delete All"
|
||||||
buttonId="delete-all"
|
buttonId="delete-all"
|
||||||
fButton={() => MessagesStore.removeByApp(appId)}
|
fButton={() => messagesStore.removeByApp(appId)}
|
||||||
buttonDisabled={!hasMessages}>
|
buttonDisabled={!hasMessages}>
|
||||||
{hasMessages ? (
|
{hasMessages ? (
|
||||||
<div style={{width: '100%'}} id="messages">
|
<div style={{width: '100%'}} id="messages">
|
||||||
|
|
@ -84,18 +84,19 @@ class Messages extends Component<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateAllWithProps = (props: IProps) => {
|
private updateAllWithProps = (props: IProps & Stores<'messagesStore'>) => {
|
||||||
const appId = Messages.appId(props);
|
const appId = Messages.appId(props);
|
||||||
|
console.log('props', props);
|
||||||
this.setState({appId});
|
this.setState({appId});
|
||||||
if (!MessagesStore.exists(appId)) {
|
if (!props.messagesStore.exists(appId)) {
|
||||||
MessagesStore.loadMore(appId);
|
props.messagesStore.loadMore(appId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private updateAll = () => this.updateAllWithProps(this.props);
|
private updateAll = () => this.updateAllWithProps(this.props);
|
||||||
|
|
||||||
private deleteMessage = (message: IMessage) => () => MessagesStore.removeSingle(message);
|
private deleteMessage = (message: IMessage) => () =>
|
||||||
|
this.props.messagesStore.removeSingle(message);
|
||||||
|
|
||||||
private renderMessage = (message: IMessage) => {
|
private renderMessage = (message: IMessage) => {
|
||||||
this.checkIfLoadMore();
|
this.checkIfLoadMore();
|
||||||
|
|
@ -113,9 +114,9 @@ class Messages extends Component<IProps, IState> {
|
||||||
|
|
||||||
private checkIfLoadMore() {
|
private checkIfLoadMore() {
|
||||||
const {appId} = this.state;
|
const {appId} = this.state;
|
||||||
if (!this.isLoadingMore && MessagesStore.canLoadMore(appId)) {
|
if (!this.isLoadingMore && this.props.messagesStore.canLoadMore(appId)) {
|
||||||
this.isLoadingMore = true;
|
this.isLoadingMore = true;
|
||||||
MessagesStore.loadMore(appId).then(() => (this.isLoadingMore = false));
|
this.props.messagesStore.loadMore(appId).then(() => (this.isLoadingMore = false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,4 +129,4 @@ class Messages extends Component<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Messages;
|
export default inject('messagesStore', 'appStore')(Messages);
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ import React, {Component, SFC} from 'react';
|
||||||
import ConfirmDialog from '../component/ConfirmDialog';
|
import ConfirmDialog from '../component/ConfirmDialog';
|
||||||
import DefaultPage from '../component/DefaultPage';
|
import DefaultPage from '../component/DefaultPage';
|
||||||
import AddEditDialog from './dialog/AddEditUserDialog';
|
import AddEditDialog from './dialog/AddEditUserDialog';
|
||||||
import UserStore from '../stores/UserStore';
|
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
import {observable} from 'mobx';
|
import {observable} from 'mobx';
|
||||||
|
import {inject, Stores} from '../inject';
|
||||||
|
|
||||||
const styles = () => ({
|
const styles = () => ({
|
||||||
wrapper: {
|
wrapper: {
|
||||||
|
|
@ -47,7 +47,7 @@ const UserRow: SFC<IRowProps> = ({name, admin, fDelete, fEdit}) => (
|
||||||
);
|
);
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Users extends Component<WithStyles<'wrapper'>> {
|
class Users extends Component<WithStyles<'wrapper'> & Stores<'userStore'>> {
|
||||||
@observable
|
@observable
|
||||||
private createDialog = false;
|
private createDialog = false;
|
||||||
@observable
|
@observable
|
||||||
|
|
@ -55,11 +55,16 @@ class Users extends Component<WithStyles<'wrapper'>> {
|
||||||
@observable
|
@observable
|
||||||
private editId: number | false = false;
|
private editId: number | false = false;
|
||||||
|
|
||||||
public componentDidMount = UserStore.refresh;
|
public componentDidMount = () => this.props.userStore.refresh();
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const users = UserStore.getItems();
|
const {
|
||||||
const {deleteId, editId, createDialog} = this;
|
deleteId,
|
||||||
|
editId,
|
||||||
|
createDialog,
|
||||||
|
props: {userStore},
|
||||||
|
} = this;
|
||||||
|
const users = userStore.getItems();
|
||||||
return (
|
return (
|
||||||
<DefaultPage
|
<DefaultPage
|
||||||
title="Users"
|
title="Users"
|
||||||
|
|
@ -95,24 +100,24 @@ class Users extends Component<WithStyles<'wrapper'>> {
|
||||||
{createDialog && (
|
{createDialog && (
|
||||||
<AddEditDialog
|
<AddEditDialog
|
||||||
fClose={() => (this.createDialog = false)}
|
fClose={() => (this.createDialog = false)}
|
||||||
fOnSubmit={UserStore.create}
|
fOnSubmit={userStore.create}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{editId !== false && (
|
{editId !== false && (
|
||||||
<AddEditDialog
|
<AddEditDialog
|
||||||
fClose={() => (this.editId = false)}
|
fClose={() => (this.editId = false)}
|
||||||
fOnSubmit={UserStore.update.bind(this, editId)}
|
fOnSubmit={userStore.update.bind(this, editId)}
|
||||||
name={UserStore.getByID(editId).name}
|
name={userStore.getByID(editId).name}
|
||||||
admin={UserStore.getByID(editId).admin}
|
admin={userStore.getByID(editId).admin}
|
||||||
isEdit={true}
|
isEdit={true}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{deleteId !== false && (
|
{deleteId !== false && (
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
title="Confirm Delete"
|
title="Confirm Delete"
|
||||||
text={'Delete ' + UserStore.getByID(deleteId).name + '?'}
|
text={'Delete ' + userStore.getByID(deleteId).name + '?'}
|
||||||
fClose={() => (this.deleteId = false)}
|
fClose={() => (this.deleteId = false)}
|
||||||
fOnSubmit={() => UserStore.remove(deleteId)}
|
fOnSubmit={() => userStore.remove(deleteId)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</DefaultPage>
|
</DefaultPage>
|
||||||
|
|
@ -120,4 +125,4 @@ class Users extends Component<WithStyles<'wrapper'>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withStyles(styles)(Users);
|
export default withStyles(styles)(inject('userStore')(Users));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue