-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: lucferbux <[email protected]>
- Loading branch information
Showing
14 changed files
with
476 additions
and
42 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import * as React from 'react'; | ||
import { UserSettings, ConfigSettings } from '~/types'; | ||
|
||
|
||
type AppContextProps = { | ||
config: ConfigSettings; | ||
user: UserSettings; | ||
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
export const AppContext = React.createContext({} as AppContextProps); | ||
|
||
export const useAppContext = (): AppContextProps => React.useContext(AppContext); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import * as React from "react"; | ||
import useTimeBasedRefresh from "./useTimeBasedRefresh"; | ||
import { ConfigSettings, PlatformType, UserSettings } from "../types"; | ||
import { POLL_INTERVAL } from "~/utilities/const"; | ||
import { useDeepCompareMemoize } from "../utilities/useDeepCompareMemoize"; | ||
|
||
export const useSettings = (): { | ||
configSettings: ConfigSettings | null; | ||
userSettings: UserSettings | null; | ||
loaded: boolean; | ||
loadError: Error | undefined; | ||
} => { | ||
const [loaded, setLoaded] = React.useState(false); | ||
const [loadError, setLoadError] = React.useState<Error>(); | ||
const [config, setConfig] = React.useState<ConfigSettings | null>(null); | ||
const [user, setUser] = React.useState<UserSettings | null>(null); | ||
const setRefreshMarker = useTimeBasedRefresh(); | ||
|
||
React.useEffect(() => { | ||
let watchHandle: ReturnType<typeof setTimeout>; | ||
let cancelled = false; | ||
const watchConfig = () => { | ||
Promise.all([fetchConfig(), fetchUser()]) | ||
.then(([config, user]) => { | ||
if (cancelled) { | ||
return; | ||
} | ||
setConfig(config); | ||
setUser(user); | ||
setLoaded(true); | ||
setLoadError(undefined); | ||
}) | ||
.catch((e) => { | ||
if (e?.message?.includes("Error getting Oauth Info for user")) { | ||
// NOTE: this endpoint only requests oauth because of the security layer, this is not an ironclad use-case | ||
// Something went wrong on the server with the Oauth, let us just log them out and refresh for them | ||
/* eslint-disable-next-line no-console */ | ||
console.error( | ||
"Something went wrong with the oauth token, please log out...", | ||
e.message, | ||
e | ||
); | ||
setRefreshMarker(new Date()); | ||
return; | ||
} | ||
setLoadError(e); | ||
}); | ||
watchHandle = setTimeout(watchConfig, POLL_INTERVAL); | ||
}; | ||
watchConfig(); | ||
|
||
return () => { | ||
cancelled = true; | ||
clearTimeout(watchHandle); | ||
}; | ||
}, [setRefreshMarker]); | ||
|
||
const retConfig = useDeepCompareMemoize<ConfigSettings | null>(config); | ||
const retUser = useDeepCompareMemoize<UserSettings | null>(user); | ||
|
||
return { configSettings: retConfig, userSettings: retUser, loaded, loadError }; | ||
}; | ||
|
||
// Mock a settings config call | ||
// TODO: replace with thea actual call once we have the endpoint | ||
export const fetchConfig = async (): Promise<ConfigSettings> => { | ||
return { | ||
platform: PlatformType.KUBEFLOW, | ||
common: { | ||
featureFlags: { | ||
modelRegistry: true, | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
// Mock a settings user call | ||
// TODO: replace with thea actual call once we have the endpoint | ||
export const fetchUser = async (): Promise<UserSettings> => { | ||
return { | ||
username: "admin", | ||
isAdmin: true, | ||
isAllowed: true, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import * as React from 'react'; | ||
import { useBrowserStorage } from '~/components/browserStorage'; | ||
|
||
|
||
export type SetTime = (refreshDateMarker: Date) => void; | ||
|
||
const useTimeBasedRefresh = (): SetTime => { | ||
const KEY_NAME = 'kf.dashboard.last.auto.refresh'; | ||
const [lastRefreshTimestamp, setLastRefreshTimestamp] = useBrowserStorage( | ||
KEY_NAME, | ||
'0', | ||
false, | ||
true, | ||
); | ||
const ref = React.useRef<{ | ||
lastRefreshTimestamp: string; | ||
setLastRefreshTimestamp: (newValue: string) => void; | ||
}>({ lastRefreshTimestamp, setLastRefreshTimestamp }); | ||
ref.current = { lastRefreshTimestamp, setLastRefreshTimestamp }; | ||
|
||
return React.useCallback<SetTime>((refreshDateMarker) => { | ||
// Intentionally avoid referential changes. We want the value at call time. | ||
// Recomputing the ref is not needed and will impact usage in hooks if it does. | ||
const lastDate = new Date(ref.current.lastRefreshTimestamp); | ||
const setNewDateString = ref.current.setLastRefreshTimestamp; | ||
|
||
/* eslint-disable no-console */ | ||
// Print into the console in case we are not refreshing or the browser has preserve log enabled | ||
console.warn('Attempting to re-trigger an auto refresh'); | ||
console.log('Last refresh was on:', lastDate); | ||
console.log('Refreshing requested after:', refreshDateMarker); | ||
|
||
lastDate.setHours(lastDate.getHours() + 1); | ||
if (lastDate < refreshDateMarker) { | ||
setNewDateString(refreshDateMarker.toString()); | ||
console.log('Logging out and refreshing'); | ||
// TODO: Replace with actual logout function | ||
//logout().then(() => window.location.reload()); | ||
} else { | ||
console.error( | ||
`We should have refreshed but it appears the last time we auto-refreshed was less than an hour ago. '${KEY_NAME}' session storage setting can be cleared for this to refresh again within the hour from the last refresh.`, | ||
); | ||
} | ||
/* eslint-enable no-console */ | ||
}, []); | ||
}; | ||
|
||
export default useTimeBasedRefresh; |
Empty file.
Oops, something went wrong.