fix: use notistack
This commit is contained in:
parent
0ca5156fed
commit
a7733b4f0a
|
|
@ -17,6 +17,7 @@
|
||||||
"mobx-react": "^6.3.0",
|
"mobx-react": "^6.3.0",
|
||||||
"mobx-utils": "^5.6.1",
|
"mobx-utils": "^5.6.1",
|
||||||
"notifyjs": "^3.0.0",
|
"notifyjs": "^3.0.0",
|
||||||
|
"notistack": "^3.0.2",
|
||||||
"react": "^17.0.0",
|
"react": "^17.0.0",
|
||||||
"react-codemirror2": "^7.2.1",
|
"react-codemirror2": "^7.2.1",
|
||||||
"react-dom": "^16.4.2",
|
"react-dom": "^16.4.2",
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import LoadingSpinner from '../common/LoadingSpinner';
|
||||||
import Navigation from './Navigation';
|
import Navigation from './Navigation';
|
||||||
import ScrollUpButton from '../common/ScrollUpButton';
|
import ScrollUpButton from '../common/ScrollUpButton';
|
||||||
import SettingsDialog from '../common/SettingsDialog';
|
import SettingsDialog from '../common/SettingsDialog';
|
||||||
import SnackBarHandler from '../snack/SnackBarHandler';
|
|
||||||
import * as config from '../config';
|
import * as config from '../config';
|
||||||
import Applications from '../application/Applications';
|
import Applications from '../application/Applications';
|
||||||
import Clients from '../client/Clients';
|
import Clients from '../client/Clients';
|
||||||
|
|
@ -20,6 +19,7 @@ import Users from '../user/Users';
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
import {ConnectionErrorBanner} from '../common/ConnectionErrorBanner';
|
import {ConnectionErrorBanner} from '../common/ConnectionErrorBanner';
|
||||||
import {useStores} from '../stores';
|
import {useStores} from '../stores';
|
||||||
|
import {SnackbarProvider} from 'notistack';
|
||||||
|
|
||||||
const useStyles = makeStyles()((theme: Theme) => ({
|
const useStyles = makeStyles()((theme: Theme) => ({
|
||||||
content: {
|
content: {
|
||||||
|
|
@ -141,7 +141,7 @@ const Layout = observer(() => {
|
||||||
<SettingsDialog fClose={() => setShowSettings(false)} />
|
<SettingsDialog fClose={() => setShowSettings(false)} />
|
||||||
)}
|
)}
|
||||||
<ScrollUpButton />
|
<ScrollUpButton />
|
||||||
<SnackBarHandler />
|
<SnackbarProvider />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
|
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
import IconButton from '@mui/material/IconButton';
|
|
||||||
import Snackbar from '@mui/material/Snackbar';
|
|
||||||
import Close from '@mui/icons-material/Close';
|
|
||||||
import React, {Component} from 'react';
|
|
||||||
import {observable, reaction} from 'mobx';
|
|
||||||
import {observer} from 'mobx-react';
|
|
||||||
import {inject, Stores} from '../inject';
|
|
||||||
|
|
||||||
@observer
|
|
||||||
class SnackBarHandler extends Component<Stores<'snackManager'>> {
|
|
||||||
private static MAX_VISIBLE_SNACK_TIME_IN_MS = 6000;
|
|
||||||
private static MIN_VISIBLE_SNACK_TIME_IN_MS = 1000;
|
|
||||||
|
|
||||||
@observable
|
|
||||||
private open = false;
|
|
||||||
@observable
|
|
||||||
private openWhen = 0;
|
|
||||||
|
|
||||||
private dispose: () => void = () => {};
|
|
||||||
|
|
||||||
public componentDidMount = () =>
|
|
||||||
(this.dispose = reaction(() => this.props.snackManager.counter, this.onNewSnack));
|
|
||||||
|
|
||||||
public componentWillUnmount = () => this.dispose();
|
|
||||||
|
|
||||||
public render() {
|
|
||||||
const {message: current, hasNext} = this.props.snackManager;
|
|
||||||
const duration = hasNext()
|
|
||||||
? SnackBarHandler.MIN_VISIBLE_SNACK_TIME_IN_MS
|
|
||||||
: SnackBarHandler.MAX_VISIBLE_SNACK_TIME_IN_MS;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Snackbar
|
|
||||||
anchorOrigin={{vertical: 'bottom', horizontal: 'left'}}
|
|
||||||
open={this.open}
|
|
||||||
autoHideDuration={duration}
|
|
||||||
onClose={this.closeCurrentSnack}
|
|
||||||
message={<span id="message-id">{current}</span>}
|
|
||||||
action={
|
|
||||||
<IconButton
|
|
||||||
key="close"
|
|
||||||
aria-label="Close"
|
|
||||||
color="inherit"
|
|
||||||
onClick={this.closeCurrentSnack}
|
|
||||||
size="large">
|
|
||||||
<Close />
|
|
||||||
</IconButton>
|
|
||||||
}
|
|
||||||
TransitionProps={{
|
|
||||||
onExited: this.openNextSnack,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private onNewSnack = () => {
|
|
||||||
const {open, openWhen} = this;
|
|
||||||
|
|
||||||
if (!open) {
|
|
||||||
this.openNextSnack();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const snackOpenSince = Date.now() - openWhen;
|
|
||||||
if (snackOpenSince > SnackBarHandler.MIN_VISIBLE_SNACK_TIME_IN_MS) {
|
|
||||||
this.closeCurrentSnack();
|
|
||||||
} else {
|
|
||||||
setTimeout(
|
|
||||||
this.closeCurrentSnack,
|
|
||||||
SnackBarHandler.MIN_VISIBLE_SNACK_TIME_IN_MS - snackOpenSince
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private openNextSnack = () => {
|
|
||||||
if (this.props.snackManager.hasNext()) {
|
|
||||||
this.open = true;
|
|
||||||
this.openWhen = Date.now();
|
|
||||||
this.props.snackManager.next();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private closeCurrentSnack = () => (this.open = false);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default inject('snackManager')(SnackBarHandler);
|
|
||||||
|
|
@ -1,30 +1,11 @@
|
||||||
import {action, observable} from 'mobx';
|
import {enqueueSnackbar} from 'notistack';
|
||||||
|
|
||||||
export interface SnackReporter {
|
export interface SnackReporter {
|
||||||
(message: string): void;
|
(message: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SnackManager {
|
export class SnackManager {
|
||||||
@observable
|
|
||||||
private messages: string[] = [];
|
|
||||||
@observable
|
|
||||||
public message: string | null = null;
|
|
||||||
@observable
|
|
||||||
public counter = 0;
|
|
||||||
|
|
||||||
@action
|
|
||||||
public next = (): void => {
|
|
||||||
if (!this.hasNext()) {
|
|
||||||
throw new Error('There is nothing here :(');
|
|
||||||
}
|
|
||||||
this.message = this.messages.shift() as string;
|
|
||||||
};
|
|
||||||
|
|
||||||
public hasNext = () => this.messages.length > 0;
|
|
||||||
|
|
||||||
@action
|
|
||||||
public snack: SnackReporter = (message: string): void => {
|
public snack: SnackReporter = (message: string): void => {
|
||||||
this.messages.push(message);
|
enqueueSnackbar({message, variant: 'info'});
|
||||||
this.counter++;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
ui/yarn.lock
18
ui/yarn.lock
|
|
@ -1473,6 +1473,11 @@ chownr@^1.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||||
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
|
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
|
||||||
|
|
||||||
|
clsx@^1.1.0:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
|
||||||
|
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
|
||||||
|
|
||||||
clsx@^2.1.1:
|
clsx@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
|
||||||
|
|
@ -2102,6 +2107,11 @@ globals@^14.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
|
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
|
||||||
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
|
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
|
||||||
|
|
||||||
|
goober@^2.0.33:
|
||||||
|
version "2.1.16"
|
||||||
|
resolved "https://registry.yarnpkg.com/goober/-/goober-2.1.16.tgz#7d548eb9b83ff0988d102be71f271ca8f9c82a95"
|
||||||
|
integrity sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==
|
||||||
|
|
||||||
graphemer@^1.4.0:
|
graphemer@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
|
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
|
||||||
|
|
@ -2815,6 +2825,14 @@ notifyjs@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/notifyjs/-/notifyjs-3.0.0.tgz#7418c9d6c0533aebaa643414214af53b521d1b28"
|
resolved "https://registry.yarnpkg.com/notifyjs/-/notifyjs-3.0.0.tgz#7418c9d6c0533aebaa643414214af53b521d1b28"
|
||||||
integrity sha1-dBjJ1sBTOuuqZDQUIUr1O1IdGyg=
|
integrity sha1-dBjJ1sBTOuuqZDQUIUr1O1IdGyg=
|
||||||
|
|
||||||
|
notistack@^3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/notistack/-/notistack-3.0.2.tgz#009799c3fccddeffac58565ba1657d27616dfabd"
|
||||||
|
integrity sha512-0R+/arLYbK5Hh7mEfR2adt0tyXJcCC9KkA2hc56FeWik2QN6Bm/S4uW+BjzDARsJth5u06nTjelSw/VSnB1YEA==
|
||||||
|
dependencies:
|
||||||
|
clsx "^1.1.0"
|
||||||
|
goober "^2.0.33"
|
||||||
|
|
||||||
object-assign@4.0.1:
|
object-assign@4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.0.1.tgz#99504456c3598b5cad4fc59c26e8a9bb107fe0bd"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.0.1.tgz#99504456c3598b5cad4fc59c26e8a9bb107fe0bd"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue