aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/editor/ConnectionStatusNotification.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/frontend/src/editor/ConnectionStatusNotification.tsx')
-rw-r--r--subprojects/frontend/src/editor/ConnectionStatusNotification.tsx108
1 files changed, 108 insertions, 0 deletions
diff --git a/subprojects/frontend/src/editor/ConnectionStatusNotification.tsx b/subprojects/frontend/src/editor/ConnectionStatusNotification.tsx
new file mode 100644
index 00000000..e402e296
--- /dev/null
+++ b/subprojects/frontend/src/editor/ConnectionStatusNotification.tsx
@@ -0,0 +1,108 @@
1import Button from '@mui/material/Button';
2import { observer } from 'mobx-react-lite';
3import { type SnackbarKey, useSnackbar } from 'notistack';
4import React, { useEffect } from 'react';
5
6import { ContrastThemeProvider } from '../theme/ThemeProvider';
7
8import type EditorStore from './EditorStore';
9
10const CONNECTING_DEBOUNCE_TIMEOUT = 250;
11
12export default observer(function ConnectionStatusNotification({
13 editorStore,
14}: {
15 editorStore: EditorStore;
16}): null {
17 const { opened, opening, connectionErrors } = editorStore;
18 const { enqueueSnackbar, closeSnackbar } = useSnackbar();
19
20 useEffect(() => {
21 if (opening) {
22 let key: SnackbarKey | undefined;
23 let timeout: number | undefined = setTimeout(() => {
24 timeout = undefined;
25 key = enqueueSnackbar('Connecting to Refinery', {
26 persist: true,
27 action: (
28 <Button onClick={() => editorStore.disconnect()} color="inherit">
29 Cancel
30 </Button>
31 ),
32 });
33 }, CONNECTING_DEBOUNCE_TIMEOUT);
34 return () => {
35 if (timeout !== undefined) {
36 clearTimeout(timeout);
37 }
38 if (key !== undefined) {
39 closeSnackbar(key);
40 }
41 };
42 }
43
44 if (connectionErrors.length >= 1) {
45 const key = enqueueSnackbar(
46 <div>
47 Connection error: <b>{connectionErrors[0]}</b>
48 {connectionErrors.length >= 2 && (
49 <>
50 {' '}
51 and <b>{connectionErrors.length - 1}</b> more{' '}
52 {connectionErrors.length >= 3 ? 'errors' : 'error'}
53 </>
54 )}
55 </div>,
56 {
57 persist: !opened,
58 variant: 'error',
59 action: opened ? (
60 <ContrastThemeProvider>
61 <Button onClick={() => editorStore.disconnect()} color="inherit">
62 Disconnect
63 </Button>
64 </ContrastThemeProvider>
65 ) : (
66 <ContrastThemeProvider>
67 <Button onClick={() => editorStore.connect()} color="inherit">
68 Reconnect
69 </Button>
70 <Button onClick={() => editorStore.disconnect()} color="inherit">
71 Cancel
72 </Button>
73 </ContrastThemeProvider>
74 ),
75 },
76 );
77 return () => closeSnackbar(key);
78 }
79
80 if (!opened) {
81 const key = enqueueSnackbar(
82 <div>
83 <b>Not connected to Refinery:</b> Some editing features might be
84 degraded
85 </div>,
86 {
87 action: (
88 <ContrastThemeProvider>
89 <Button onClick={() => editorStore.connect()}>Reconnect</Button>
90 </ContrastThemeProvider>
91 ),
92 },
93 );
94 return () => closeSnackbar(key);
95 }
96
97 return () => {};
98 }, [
99 editorStore,
100 opened,
101 opening,
102 connectionErrors,
103 closeSnackbar,
104 enqueueSnackbar,
105 ]);
106
107 return null;
108});