mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-28 17:50:57 -05:00
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:
parent
68790dbe1b
commit
dbc592e6d7
6 changed files with 36 additions and 14 deletions
|
@ -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>
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue