better error messages for the loading-screen (#87)

better error messages for the loading-screen

Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2020-05-30 16:22:07 +02:00 committed by GitHub
parent 68790dbe1b
commit dbc592e6d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 14 deletions

View file

@ -3,7 +3,7 @@ import { BackendConfigState } from '../redux/backend-config/types'
import { expectResponseCode, getBackendUrl } from '../utils/apiUtils' import { expectResponseCode, getBackendUrl } from '../utils/apiUtils'
export const getBackendConfig = async (): Promise<BackendConfigState> => { export const getBackendConfig = async (): Promise<BackendConfigState> => {
const response = await fetch(getBackendUrl() + '/backend-config.json') const response = await fetch(getBackendUrl() + '/config')
expectResponseCode(response) expectResponseCode(response)
return await response.json() as Promise<BackendConfigState> return await response.json() as Promise<BackendConfigState>
} }

View file

@ -1,13 +1,14 @@
import React, { Fragment, useEffect, useState } from 'react' import React, { Fragment, useEffect, useState } from 'react'
import { useLocation } from 'react-router' import { useLocation } from 'react-router'
import { setUp } from '../../initializers' import { setUp, InitTask } from '../../initializers'
import './application-loader.scss' import './application-loader.scss'
import { LoadingScreen } from './loading-screen' import { LoadingScreen } from './loading-screen'
export const ApplicationLoader: React.FC = ({ children }) => { export const ApplicationLoader: React.FC = ({ children }) => {
const [failed, setFailed] = useState<boolean>(false) const [failedTitle, setFailedTitle] = useState<string>('')
const [doneTasks, setDoneTasks] = useState<number>(0) const [doneTasks, setDoneTasks] = useState<number>(0)
const [initTasks, setInitTasks] = useState<Promise<void>[]>([]) const [initTasks, setInitTasks] = useState<InitTask[]>([])
const { pathname } = useLocation() const { pathname } = useLocation()
const runTask = async (task: Promise<void>): Promise<void> => { const runTask = async (task: Promise<void>): Promise<void> => {
@ -25,16 +26,16 @@ export const ApplicationLoader: React.FC = ({ children }) => {
useEffect(() => { useEffect(() => {
for (const task of initTasks) { for (const task of initTasks) {
runTask(task).catch(reason => { runTask(task.task).catch((reason: Error) => {
setFailed(true)
console.error(reason) console.error(reason)
setFailedTitle(task.name)
}) })
} }
}, [initTasks]) }, [initTasks])
return ( return (
doneTasks < initTasks.length || initTasks.length === 0 doneTasks < initTasks.length || initTasks.length === 0
? <LoadingScreen failed={failed}/> ? <LoadingScreen failedTitle={failedTitle}/>
: <Fragment>{children}</Fragment> : <Fragment>{children}</Fragment>
) )
} }

View file

@ -3,18 +3,25 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { Alert } from 'react-bootstrap' import { Alert } from 'react-bootstrap'
export interface LoadingScreenProps { export interface LoadingScreenProps {
failed: boolean failedTitle: string
} }
export const LoadingScreen: React.FC<LoadingScreenProps> = ({ failed }) => { export const LoadingScreen: React.FC<LoadingScreenProps> = ({ failedTitle }) => {
return ( return (
<div className="loader middle"> <div className="loader middle">
<div className="icon"> <div className="icon">
<FontAwesomeIcon icon="file-alt" size="6x" <FontAwesomeIcon icon="file-alt" size="6x"
className={failed ? 'animation-shake' : 'animation-pulse'}/> className={failedTitle ? 'animation-shake' : 'animation-pulse'}/>
</div> </div>
{ {
failed ? <Alert variant={'danger'}>An error occurred while loading the application!</Alert> : null failedTitle !== ''
? (
<Alert variant={'danger'}>
The task '{failedTitle}' failed.<br/>
For further information look into the browser console.
</Alert>
)
: null
} }
</div> </div>
) )

View file

@ -31,7 +31,7 @@ import 'moment/locale/vi'
import 'moment/locale/zh-cn' import 'moment/locale/zh-cn'
import 'moment/locale/zh-tw' import 'moment/locale/zh-tw'
export const setUpI18n: () => Promise<void> = async () => { export const setUpI18n = async (): Promise<void> => {
await i18n await i18n
.use(Backend) .use(Backend)
.use(LanguageDetector) .use(LanguageDetector)

View file

@ -9,6 +9,20 @@ const customDelay: () => Promise<void> = async () => {
} }
} }
export const setUp: (baseUrl: string) => Promise<void>[] = (baseUrl) => { export interface InitTask {
return [setUpI18n(), loadAllConfig(baseUrl), customDelay()] name: string
task: Promise<void>
}
export const setUp = (baseUrl: string): InitTask[] => {
return [{
name: 'Load Translations',
task: setUpI18n()
}, {
name: 'Load config',
task: loadAllConfig(baseUrl)
}, {
name: 'Add Delay',
task: customDelay()
}]
} }