@@ -21,10 +21,12 @@ import { SingleTaskView } from './pages/SingleTaskView/SingleTaskView';
21
21
import { createTheme , ThemeProvider , StyledEngineProvider , adaptV4Theme } from '@mui/material/styles' ;
22
22
import { GlobalStyles } from '../themes/GlobalStyles' ;
23
23
import CssBaseline from '@mui/material/CssBaseline' ;
24
- import { FailedRefresh , meState } from '../cache' ;
24
+ import { FailedRefresh , mePreferences , meState } from '../cache' ;
25
25
import { Reporting } from './pages/Reporting/Reporting' ;
26
26
import { MitreAttack } from './pages/MITRE_ATTACK/MitreAttack' ;
27
27
import { Tags } from './pages/Tags/Tags' ;
28
+ import { Tooltip } from 'react-tooltip' ;
29
+ import { useQuery , gql } from '@apollo/client' ;
28
30
//background-color: #282c34;
29
31
import { Route , Routes } from 'react-router-dom' ;
30
32
import { useInterval } from './utilities/Time' ;
@@ -35,29 +37,23 @@ import { ToastContainer } from 'react-toastify';
35
37
import "react-toastify/dist/ReactToastify.css" ;
36
38
import { Eventing } from "./pages/Eventing/Eventing" ;
37
39
import { InviteForm } from "./pages/Login/InviteForm" ;
40
+ import { snackActions } from "./utilities/Snackbar" ;
38
41
42
+ const userSettingsQuery = gql `
43
+ query getUserSettings {
44
+ getOperatorPreferences {
45
+ status
46
+ error
47
+ preferences
48
+ }
49
+ }
50
+ ` ;
39
51
40
52
41
53
export function App ( props ) {
42
54
const me = useReactiveVar ( meState ) ;
55
+ const preferences = useReactiveVar ( mePreferences ) ;
43
56
const [ themeMode , themeToggler ] = useDarkMode ( ) ;
44
- const localStorageFontSize = localStorage . getItem ( `${ me ?. user ?. user_id || 0 } -fontSize` ) ;
45
- const initialLocalStorageFontSizeValue = localStorageFontSize === null ? 12 : parseInt ( localStorageFontSize ) ;
46
- const localStorageFontFamily = localStorage . getItem ( `${ me ?. user ?. user_id || 0 } -fontFamily` ) ;
47
- const initialLocalStorageFontFamilyValue = localStorageFontFamily === null ? [
48
- '-apple-system' ,
49
- 'BlinkMacSystemFont' ,
50
- '"Segoe UI"' ,
51
- 'Roboto' ,
52
- '"Helvetica Neue"' ,
53
- 'Arial' ,
54
- 'sans-serif' ,
55
- '"Apple Color Emoji"' ,
56
- '"Segoe UI Emoji"' ,
57
- '"Segoe UI Symbol"' ,
58
- ] . join ( ',' ) : localStorageFontFamily ;
59
- const localStorageTopColor = localStorage . getItem ( `${ me ?. user ?. user_id || 0 } -topColor` ) ;
60
- const initialLocalStorageTopColorValue = localStorageTopColor === null ? "#3c4d67" : localStorageTopColor ;
61
57
const theme = React . useMemo (
62
58
( ) =>
63
59
createTheme ( adaptV4Theme ( {
@@ -122,16 +118,35 @@ export function App(props) {
122
118
pageHeaderText : {
123
119
main : 'white' ,
124
120
} ,
125
- topAppBarColor : initialLocalStorageTopColorValue ,
121
+ topAppBarColor : preferences ?. topColor ,
126
122
typography : {
127
- fontSize : initialLocalStorageFontSizeValue ,
128
- fontFamily : initialLocalStorageFontFamilyValue
123
+ fontSize : preferences ?. fontSize ,
124
+ fontFamily : preferences ?. fontFamily
129
125
} ,
130
126
} ) ) ,
131
- [ themeMode ]
127
+ [ themeMode , preferences . topColor , preferences . fontSize , preferences . fontFamily ]
132
128
) ;
133
129
const mountedRef = React . useRef ( true ) ;
134
130
const [ openRefreshDialog , setOpenRefreshDialog ] = React . useState ( false ) ;
131
+ const [ loadingPreference , setLoadingPreferences ] = React . useState ( true ) ;
132
+ useQuery ( userSettingsQuery , {
133
+ onCompleted : ( data ) => {
134
+ //console.log("got preferences", data.getOperatorPreferences.preferences)
135
+ if ( data . getOperatorPreferences . status === "success" ) {
136
+ if ( data . getOperatorPreferences . preferences !== null ) {
137
+ mePreferences ( data . getOperatorPreferences . preferences ) ;
138
+ }
139
+ } else {
140
+ snackActions . error ( `Failed to get user preferences:\n${ data . getOperatorPreferences . error } ` ) ;
141
+ }
142
+ setLoadingPreferences ( false ) ;
143
+ } ,
144
+ onError : ( error ) => {
145
+ console . log ( error ) ;
146
+ snackActions . error ( error . message ) ;
147
+ setLoadingPreferences ( false ) ;
148
+ }
149
+ } )
135
150
useInterval ( ( ) => {
136
151
// interval should run every 10 minutes (600000 milliseconds) to check JWT status
137
152
let millisecondsLeft = JWTTimeLeft ( ) ;
@@ -145,11 +160,16 @@ export function App(props) {
145
160
}
146
161
}
147
162
} , 600000 , mountedRef , mountedRef ) ;
163
+ if ( loadingPreference ) {
164
+ // make sure we've loaded preferences before loading actual app content
165
+ return null
166
+ }
148
167
return (
149
168
< StyledEngineProvider injectFirst >
150
169
< ThemeProvider theme = { theme } >
151
170
< GlobalStyles theme = { theme } />
152
171
< CssBaseline />
172
+ < Tooltip id = { "my-tooltip" } style = { { zIndex : 100000 } } />
153
173
< ToastContainer limit = { 2 } autoClose = { 3000 }
154
174
theme = { themeMode }
155
175
style = { { maxWidth : "100%" , minWidth : "40%" , width : "40%" , marginTop : "20px" , display : "flex" , flexWrap : "wrap" ,
0 commit comments