mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-25 04:24:43 -04:00
Restructures + New Evironment Variables (#1230)
* Use document base uri for react router Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Rename getAndSetUser to fetchAndSetUser Getter should be reserved for simple get functions. Everything that does a bit more logic should use a more meaningful verb. Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Rename getFrontPageContent to fetchFrontPageContent Getter should be reserved for simple get functions. Everything that does a bit more logic should use a more meaningful verb. Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Reformat code Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Use PUBLIC_URL env var in index.html Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Introduce new environment variables For better testing (especially if you have multiple endpoints) this commit introduces REACT_APP_BACKEND_BASE_URL, REACT_APP_FRONTEND_ASSETS_URL and REACT_APP_CUSTOMIZE_ASSETS_URL Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Remove redundant license information Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Remove redundant license information Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Fix rebase issues Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Remove unused file Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Correct parameter Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Fix run tasks Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Force use of bash Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Fix link to cypress picture Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * revert change Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * fix url Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Remove license info Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Revert rebase issues Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Add missing banner code Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Fix test url Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Useless change to trigger github Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Don't set backend base url because this break the mock mode detection Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> Co-authored-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
parent
9cf7980334
commit
2c5a03b3ee
52 changed files with 193 additions and 162 deletions
|
@ -1,21 +1,24 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React, { Suspense, useCallback, useEffect, useState } from 'react'
|
||||
import { useFrontendBaseUrl } from '../../hooks/common/use-frontend-base-url'
|
||||
import { useBackendBaseUrl } from '../../hooks/common/use-backend-base-url'
|
||||
import './application-loader.scss'
|
||||
import { createSetUpTaskList, InitTask } from './initializers'
|
||||
import { LoadingScreen } from './loading-screen'
|
||||
import { useCustomizeAssetsUrl } from '../../hooks/common/use-customize-assets-url'
|
||||
import { useFrontendAssetsUrl } from '../../hooks/common/use-frontend-assets-url'
|
||||
|
||||
export const ApplicationLoader: React.FC = ({ children }) => {
|
||||
const frontendUrl = useFrontendBaseUrl()
|
||||
const frontendAssetsUrl = useFrontendAssetsUrl()
|
||||
const backendBaseUrl = useBackendBaseUrl()
|
||||
const customizeAssetsUrl = useCustomizeAssetsUrl()
|
||||
|
||||
const setUpTasks = useCallback(() => {
|
||||
return createSetUpTaskList(frontendUrl)
|
||||
}, [frontendUrl])
|
||||
const setUpTasks = useCallback(() => createSetUpTaskList(frontendAssetsUrl, customizeAssetsUrl, backendBaseUrl),
|
||||
[backendBaseUrl, customizeAssetsUrl, frontendAssetsUrl])
|
||||
|
||||
const [failedTitle, setFailedTitle] = useState<string>('')
|
||||
const [doneTasks, setDoneTasks] = useState<number>(0)
|
||||
|
|
|
@ -5,16 +5,10 @@
|
|||
*/
|
||||
|
||||
import { getConfig } from '../../../api/config'
|
||||
import { setApiUrl } from '../../../redux/api-url/methods'
|
||||
import { setBanner } from '../../../redux/banner/methods'
|
||||
import { setConfig } from '../../../redux/config/methods'
|
||||
import { getAndSetUser } from '../../login-page/auth/utils'
|
||||
|
||||
export const loadAllConfig: (baseUrl: string) => Promise<void> = async (baseUrl) => {
|
||||
setApiUrl({
|
||||
apiUrl: (process.env.REACT_APP_BACKEND || baseUrl) + '/api/private'
|
||||
})
|
||||
|
||||
export const fetchFrontendConfig = async (): Promise<void> => {
|
||||
const config = await getConfig()
|
||||
if (!config) {
|
||||
return Promise.reject(new Error('Config empty!'))
|
||||
|
@ -29,6 +23,4 @@ export const loadAllConfig: (baseUrl: string) => Promise<void> = async (baseUrl)
|
|||
show: banner.text !== '' && banner.timestamp !== lastAcknowledgedTimestamp
|
||||
})
|
||||
}
|
||||
|
||||
await getAndSetUser()
|
||||
}
|
|
@ -10,7 +10,7 @@ import Backend from 'i18next-http-backend'
|
|||
import { Settings } from 'luxon'
|
||||
import { initReactI18next } from 'react-i18next'
|
||||
|
||||
export const setUpI18n = async (): Promise<void> => {
|
||||
export const setUpI18n = async (frontendAssetsUrl: string): Promise<void> => {
|
||||
await i18n
|
||||
.use(Backend)
|
||||
.use(LanguageDetector)
|
||||
|
@ -19,7 +19,7 @@ export const setUpI18n = async (): Promise<void> => {
|
|||
fallbackLng: 'en',
|
||||
debug: process.env.NODE_ENV !== 'production',
|
||||
backend: {
|
||||
loadPath: '/locales/{{lng}}.json'
|
||||
loadPath: `${ frontendAssetsUrl }/locales/{{lng}}.json`
|
||||
},
|
||||
|
||||
interpolation: {
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { loadAllConfig } from './configLoader'
|
||||
import { setUpI18n } from './i18n'
|
||||
import { refreshHistoryState } from '../../../redux/history/methods'
|
||||
import { setApiUrl } from '../../../redux/api-url/methods'
|
||||
import { fetchAndSetUser } from '../../login-page/auth/utils'
|
||||
import { fetchFrontendConfig } from './fetch-frontend-config'
|
||||
|
||||
const customDelay: () => Promise<void> = async () => {
|
||||
if (window.localStorage.getItem('customDelay')) {
|
||||
|
@ -21,13 +23,20 @@ export interface InitTask {
|
|||
task: Promise<void>
|
||||
}
|
||||
|
||||
export const createSetUpTaskList = (baseUrl: string): InitTask[] => {
|
||||
export const createSetUpTaskList = (frontendAssetsUrl: string, customizeAssetsUrl: string, backendBaseUrl: string): InitTask[] => {
|
||||
setApiUrl({
|
||||
apiUrl: `${ backendBaseUrl }/api/private`
|
||||
})
|
||||
|
||||
return [{
|
||||
name: 'Load Translations',
|
||||
task: setUpI18n()
|
||||
task: setUpI18n(frontendAssetsUrl)
|
||||
}, {
|
||||
name: 'Load config',
|
||||
task: loadAllConfig(baseUrl)
|
||||
task: fetchFrontendConfig()
|
||||
}, {
|
||||
name: 'Fetch user information',
|
||||
task: fetchAndSetUser()
|
||||
}, {
|
||||
name: 'Load history state',
|
||||
task: refreshHistoryState()
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { getFrontPageContent } from '../requests'
|
||||
import { useFrontendBaseUrl } from '../../../hooks/common/use-frontend-base-url'
|
||||
import { fetchFrontPageContent } from '../requests'
|
||||
import { useCustomizeAssetsUrl } from '../../../hooks/common/use-customize-assets-url'
|
||||
|
||||
const MARKDOWN_WHILE_LOADING = ':zzz: {message}'
|
||||
const MARKDOWN_IF_ERROR = ':::danger\n' +
|
||||
|
@ -17,13 +17,13 @@ const MARKDOWN_IF_ERROR = ':::danger\n' +
|
|||
export const useIntroPageContent = (): string => {
|
||||
const { t } = useTranslation()
|
||||
const [content, setContent] = useState<string>(() => MARKDOWN_WHILE_LOADING.replace('{message}', t('landing.intro.markdownWhileLoading')))
|
||||
const frontendBaseUrl = useFrontendBaseUrl()
|
||||
const customizeAssetsUrl = useCustomizeAssetsUrl()
|
||||
|
||||
useEffect(() => {
|
||||
getFrontPageContent(frontendBaseUrl)
|
||||
fetchFrontPageContent(customizeAssetsUrl)
|
||||
.then((content) => setContent(content))
|
||||
.catch(() => setContent(MARKDOWN_IF_ERROR.replace('{message}', t('landing.intro.markdownLoadingError'))))
|
||||
}, [frontendBaseUrl, t])
|
||||
}, [customizeAssetsUrl, t])
|
||||
|
||||
return content
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
import { defaultFetchConfig, expectResponseCode } from '../../api/utils'
|
||||
|
||||
export const getFrontPageContent = async (baseUrl: string): Promise<string> => {
|
||||
const response = await fetch(baseUrl + '/intro.md', {
|
||||
export const fetchFrontPageContent = async (customizeAssetsUrl: string): Promise<string> => {
|
||||
const response = await fetch(customizeAssetsUrl + '/intro.md', {
|
||||
...defaultFetchConfig,
|
||||
method: 'GET'
|
||||
})
|
||||
|
|
|
@ -26,7 +26,7 @@ export const PoweredByLinks: React.FC = () => {
|
|||
<ExternalLink href={ links.webpage } text="HedgeDoc"/>
|
||||
</Trans>
|
||||
|
|
||||
<TranslatedInternalLink href='/n/release-notes' i18nKey='landing.footer.releases'/>
|
||||
<TranslatedInternalLink href="/n/release-notes" i18nKey="landing.footer.releases"/>
|
||||
{
|
||||
specialUrls.map(([i18nKey, href]) =>
|
||||
<Fragment key={ i18nKey }>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import { getMe } from '../../../api/me'
|
||||
import { setUser } from '../../../redux/user/methods'
|
||||
|
||||
export const getAndSetUser: () => (Promise<void>) = async () => {
|
||||
export const fetchAndSetUser: () => (Promise<void>) = async () => {
|
||||
const me = await getMe()
|
||||
setUser({
|
||||
id: me.id,
|
||||
|
|
|
@ -12,7 +12,7 @@ import { Link } from 'react-router-dom'
|
|||
import { doInternalLogin } from '../../../api/auth'
|
||||
import { ApplicationState } from '../../../redux'
|
||||
import { ShowIf } from '../../common/show-if/show-if'
|
||||
import { getAndSetUser } from './utils'
|
||||
import { fetchAndSetUser } from './utils'
|
||||
|
||||
export const ViaInternal: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -23,7 +23,7 @@ export const ViaInternal: React.FC = () => {
|
|||
|
||||
const onLoginSubmit = useCallback((event: FormEvent) => {
|
||||
doInternalLogin(username, password)
|
||||
.then(() => getAndSetUser())
|
||||
.then(() => fetchAndSetUser())
|
||||
.catch(() => setError(true))
|
||||
event.preventDefault()
|
||||
}, [username, password])
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React, { FormEvent, useCallback, useState } from 'react'
|
||||
|
@ -11,7 +11,7 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
import { useSelector } from 'react-redux'
|
||||
import { doLdapLogin } from '../../../api/auth'
|
||||
import { ApplicationState } from '../../../redux'
|
||||
import { getAndSetUser } from './utils'
|
||||
import { fetchAndSetUser } from './utils'
|
||||
|
||||
export const ViaLdap: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
@ -25,7 +25,7 @@ export const ViaLdap: React.FC = () => {
|
|||
|
||||
const onLoginSubmit = useCallback((event: FormEvent) => {
|
||||
doLdapLogin(username, password)
|
||||
.then(() => getAndSetUser())
|
||||
.then(() => fetchAndSetUser())
|
||||
.catch(() => setError(true))
|
||||
event.preventDefault()
|
||||
}, [username, password])
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React, { FormEvent, useState } from 'react'
|
||||
import { Alert, Button, Card, Form } from 'react-bootstrap'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { doOpenIdLogin } from '../../../api/auth'
|
||||
import { getAndSetUser } from './utils'
|
||||
import { fetchAndSetUser } from './utils'
|
||||
|
||||
export const ViaOpenId: React.FC = () => {
|
||||
useTranslation()
|
||||
|
@ -16,7 +16,7 @@ export const ViaOpenId: React.FC = () => {
|
|||
const [error, setError] = useState(false)
|
||||
const doAsyncLogin: (() => Promise<void>) = async () => {
|
||||
await doOpenIdLogin(openId)
|
||||
await getAndSetUser()
|
||||
await fetchAndSetUser()
|
||||
}
|
||||
|
||||
const onFormSubmit = (event: FormEvent) => {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { Alert } from 'react-bootstrap'
|
||||
import { ShowIf } from '../../../common/show-if/show-if'
|
||||
import { useFrontendBaseUrl } from '../../../../hooks/common/use-frontend-base-url'
|
||||
|
||||
export interface GraphvizFrameProps {
|
||||
code: string
|
||||
|
@ -26,6 +27,8 @@ export const GraphvizFrame: React.FC<GraphvizFrameProps> = ({ code }) => {
|
|||
.forEach(child => child.remove())
|
||||
}, [])
|
||||
|
||||
const frontendBaseUrl = useFrontendBaseUrl()
|
||||
|
||||
useEffect(() => {
|
||||
if (!container.current) {
|
||||
return
|
||||
|
@ -34,7 +37,7 @@ export const GraphvizFrame: React.FC<GraphvizFrameProps> = ({ code }) => {
|
|||
|
||||
import(/* webpackChunkName: "d3-graphviz" */'@hpcc-js/wasm')
|
||||
.then((wasmPlugin) => {
|
||||
wasmPlugin.wasmFolder('/static/js')
|
||||
wasmPlugin.wasmFolder(`${ frontendBaseUrl }/static/js`)
|
||||
})
|
||||
.then(() => import(/* webpackChunkName: "d3-graphviz" */ 'd3-graphviz'))
|
||||
.then((graphvizImport) => {
|
||||
|
@ -53,7 +56,7 @@ export const GraphvizFrame: React.FC<GraphvizFrameProps> = ({ code }) => {
|
|||
.catch(() => {
|
||||
console.error('error while loading graphviz')
|
||||
})
|
||||
}, [code, error, showError])
|
||||
}, [code, error, frontendBaseUrl, showError])
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React, { ChangeEvent, FormEvent, useEffect, useState } from 'react'
|
||||
|
@ -10,7 +10,7 @@ import { Trans, useTranslation } from 'react-i18next'
|
|||
import { useSelector } from 'react-redux'
|
||||
import { updateDisplayName } from '../../../api/me'
|
||||
import { ApplicationState } from '../../../redux'
|
||||
import { getAndSetUser } from '../../login-page/auth/utils'
|
||||
import { fetchAndSetUser } from '../../login-page/auth/utils'
|
||||
|
||||
export const ProfileDisplayName: React.FC = () => {
|
||||
const regexInvalidDisplayName = /^\s*$/
|
||||
|
@ -37,7 +37,7 @@ export const ProfileDisplayName: React.FC = () => {
|
|||
|
||||
const doAsyncChange = async () => {
|
||||
await updateDisplayName(displayName)
|
||||
await getAndSetUser()
|
||||
await fetchAndSetUser()
|
||||
}
|
||||
|
||||
const changeNameSubmit = (event: FormEvent) => {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React, { FormEvent, Fragment, useCallback, useEffect, useState } from 'react'
|
||||
|
@ -13,8 +13,7 @@ import { doInternalRegister } from '../../api/auth'
|
|||
import { ApplicationState } from '../../redux'
|
||||
import { TranslatedExternalLink } from '../common/links/translated-external-link'
|
||||
import { ShowIf } from '../common/show-if/show-if'
|
||||
import { getAndSetUser } from '../login-page/auth/utils'
|
||||
import { SpecialUrls } from '../../api/config/types'
|
||||
import { fetchAndSetUser } from '../login-page/auth/utils'
|
||||
|
||||
export enum RegisterError {
|
||||
NONE = 'none',
|
||||
|
@ -25,7 +24,7 @@ export enum RegisterError {
|
|||
export const RegisterPage: React.FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const allowRegister = useSelector((state: ApplicationState) => state.config.allowRegister)
|
||||
const specialUrls: SpecialUrls = useSelector((state: ApplicationState) => state.config.specialUrls)
|
||||
const specialUrls = useSelector((state: ApplicationState) => state.config.specialUrls)
|
||||
const userExists = useSelector((state: ApplicationState) => !!state.user)
|
||||
|
||||
const [username, setUsername] = useState('')
|
||||
|
@ -36,7 +35,7 @@ export const RegisterPage: React.FC = () => {
|
|||
|
||||
const doRegisterSubmit = useCallback((event: FormEvent) => {
|
||||
doInternalRegister(username, password)
|
||||
.then(() => getAndSetUser())
|
||||
.then(() => fetchAndSetUser())
|
||||
.catch((err: Error) => {
|
||||
console.error(err)
|
||||
setError(err.message === RegisterError.USERNAME_EXISTING ? err.message : RegisterError.OTHER)
|
||||
|
@ -61,83 +60,84 @@ export const RegisterPage: React.FC = () => {
|
|||
}
|
||||
|
||||
return <Fragment>
|
||||
<div className='my-3'>
|
||||
<h1 className='mb-4'><Trans i18nKey='login.register.title'/></h1>
|
||||
<Row className='h-100 d-flex justify-content-center'>
|
||||
<div className="my-3">
|
||||
<h1 className="mb-4"><Trans i18nKey="login.register.title"/></h1>
|
||||
<Row className="h-100 d-flex justify-content-center">
|
||||
<Col lg={ 6 }>
|
||||
<Card className='bg-dark mb-4 text-start'>
|
||||
<Card className="bg-dark mb-4 text-start">
|
||||
<Card.Body>
|
||||
<Form onSubmit={ doRegisterSubmit }>
|
||||
<Form.Group controlId='username'>
|
||||
<Form.Label><Trans i18nKey='login.auth.username'/></Form.Label>
|
||||
<Form.Group controlId="username">
|
||||
<Form.Label><Trans i18nKey="login.auth.username"/></Form.Label>
|
||||
<Form.Control
|
||||
type='text'
|
||||
size='sm'
|
||||
type="text"
|
||||
size="sm"
|
||||
value={ username }
|
||||
isValid={ username !== '' }
|
||||
onChange={ (event) => setUsername(event.target.value) }
|
||||
placeholder={ t('login.auth.username') }
|
||||
className='bg-dark text-light'
|
||||
autoComplete='username'
|
||||
className="bg-dark text-light"
|
||||
autoComplete="username"
|
||||
autoFocus={ true }
|
||||
required
|
||||
/>
|
||||
<Form.Text><Trans i18nKey='login.register.usernameInfo'/></Form.Text>
|
||||
<Form.Text><Trans i18nKey="login.register.usernameInfo"/></Form.Text>
|
||||
</Form.Group>
|
||||
<Form.Group controlId='password'>
|
||||
<Form.Label><Trans i18nKey='login.auth.password'/></Form.Label>
|
||||
<Form.Group controlId="password">
|
||||
<Form.Label><Trans i18nKey="login.auth.password"/></Form.Label>
|
||||
<Form.Control
|
||||
type='password'
|
||||
size='sm'
|
||||
type="password"
|
||||
size="sm"
|
||||
isValid={ password !== '' && password.length >= 8 }
|
||||
onChange={ (event) => setPassword(event.target.value) }
|
||||
placeholder={ t('login.auth.password') }
|
||||
className='bg-dark text-light'
|
||||
className="bg-dark text-light"
|
||||
minLength={ 8 }
|
||||
autoComplete='new-password'
|
||||
autoComplete="new-password"
|
||||
required
|
||||
/>
|
||||
<Form.Text><Trans i18nKey='login.register.passwordInfo'/></Form.Text>
|
||||
<Form.Text><Trans i18nKey="login.register.passwordInfo"/></Form.Text>
|
||||
</Form.Group>
|
||||
<Form.Group controlId='re-password'>
|
||||
<Form.Label><Trans i18nKey='login.register.passwordAgain'/></Form.Label>
|
||||
<Form.Group controlId="re-password">
|
||||
<Form.Label><Trans i18nKey="login.register.passwordAgain"/></Form.Label>
|
||||
<Form.Control
|
||||
type='password'
|
||||
size='sm'
|
||||
type="password"
|
||||
size="sm"
|
||||
isInvalid={ passwordAgain !== '' && password !== passwordAgain }
|
||||
isValid={ passwordAgain !== '' && password === passwordAgain }
|
||||
onChange={ (event) => setPasswordAgain(event.target.value) }
|
||||
placeholder={ t('login.register.passwordAgain') }
|
||||
className='bg-dark text-light'
|
||||
autoComplete='new-password'
|
||||
className="bg-dark text-light"
|
||||
autoComplete="new-password"
|
||||
required
|
||||
/>
|
||||
</Form.Group>
|
||||
<ShowIf condition={ !!specialUrls?.termsOfUse || !!specialUrls?.privacy }>
|
||||
<Trans i18nKey='login.register.infoTermsPrivacy'/>
|
||||
<ShowIf condition={ !!specialUrls.termsOfUse || !!specialUrls.privacy }>
|
||||
<Trans i18nKey="login.register.infoTermsPrivacy"/>
|
||||
<ul>
|
||||
<ShowIf condition={ !!specialUrls?.termsOfUse }>
|
||||
<ShowIf condition={ !!specialUrls.termsOfUse }>
|
||||
<li>
|
||||
<TranslatedExternalLink i18nKey='landing.footer.termsOfUse' href={ specialUrls.termsOfUse }/>
|
||||
<TranslatedExternalLink i18nKey="landing.footer.termsOfUse"
|
||||
href={ specialUrls.termsOfUse ?? '' }/>
|
||||
</li>
|
||||
</ShowIf>
|
||||
<ShowIf condition={ !!specialUrls?.privacy }>
|
||||
<ShowIf condition={ !!specialUrls.privacy }>
|
||||
<li>
|
||||
<TranslatedExternalLink i18nKey='landing.footer.privacy' href={ specialUrls.privacy }/>
|
||||
<TranslatedExternalLink i18nKey="landing.footer.privacy" href={ specialUrls.privacy ?? '' }/>
|
||||
</li>
|
||||
</ShowIf>
|
||||
</ul>
|
||||
</ShowIf>
|
||||
<Button
|
||||
variant='primary'
|
||||
type='submit'
|
||||
variant="primary"
|
||||
type="submit"
|
||||
block={ true }
|
||||
disabled={ !ready }>
|
||||
<Trans i18nKey='login.register.title'/>
|
||||
<Trans i18nKey="login.register.title"/>
|
||||
</Button>
|
||||
</Form>
|
||||
<br/>
|
||||
<Alert show={ error !== RegisterError.NONE } variant='danger'>
|
||||
<Alert show={ error !== RegisterError.NONE } variant="danger">
|
||||
<Trans i18nKey={ `login.register.error.${ error }` }/>
|
||||
</Alert>
|
||||
</Card.Body>
|
||||
|
|
9
src/hooks/common/use-backend-base-url.ts
Normal file
9
src/hooks/common/use-backend-base-url.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export const useBackendBaseUrl = (): string => {
|
||||
return process.env.REACT_APP_BACKEND_BASE_URL ?? '/mock-backend'
|
||||
}
|
12
src/hooks/common/use-customize-assets-url.ts
Normal file
12
src/hooks/common/use-customize-assets-url.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { useBackendBaseUrl } from './use-backend-base-url'
|
||||
|
||||
export const useCustomizeAssetsUrl = (): string => {
|
||||
const backendBaseUrl = useBackendBaseUrl()
|
||||
return (process.env.REACT_APP_CUSTOMIZE_ASSETS_URL || `${ backendBaseUrl }/public`)
|
||||
}
|
12
src/hooks/common/use-frontend-assets-url.ts
Normal file
12
src/hooks/common/use-frontend-assets-url.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { useFrontendBaseUrl } from './use-frontend-base-url'
|
||||
|
||||
export const useFrontendAssetsUrl = (): string => {
|
||||
const frontendBaseUrl = useFrontendBaseUrl()
|
||||
return (process.env.REACT_APP_FRONTEND_ASSETS_URL || frontendBaseUrl)
|
||||
}
|
|
@ -27,10 +27,11 @@ import { isTestMode } from './utils/test-modes'
|
|||
const EditorPage = React.lazy(() => import(/* webpackPrefetch: true *//* webpackChunkName: "editor" */ './components/editor-page/editor-page'))
|
||||
const RenderPage = React.lazy(() => import (/* webpackPrefetch: true *//* webpackChunkName: "renderPage" */ './components/render-page/render-page'))
|
||||
const DocumentReadOnlyPage = React.lazy(() => import (/* webpackPrefetch: true *//* webpackChunkName: "documentReadOnly" */ './components/document-read-only-page/document-read-only-page'))
|
||||
const baseUrl = new URL(document.head.baseURI).pathname
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={ store }>
|
||||
<Router>
|
||||
<Router basename={ baseUrl }>
|
||||
<ApplicationLoader>
|
||||
<ErrorBoundary>
|
||||
<Switch>
|
||||
|
@ -93,4 +94,3 @@ if (isTestMode()) {
|
|||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
serviceWorkerRegistration.unregister()
|
||||
|
||||
|
|
|
@ -9,5 +9,5 @@ export const isTestMode = (): boolean => {
|
|||
}
|
||||
|
||||
export const isMockMode = (): boolean => {
|
||||
return process.env.REACT_APP_BACKEND === undefined
|
||||
return process.env.REACT_APP_BACKEND_BASE_URL === undefined
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue