mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-13 22:54:42 -04:00
Code improvements (#1086)
* Extract code into hook * Refactor code to remove let * Reformat code * Extract version-info-modal into components * Use main block in landinglayout * Add fixedWidth and classname attribute to IconButton Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
This commit is contained in:
parent
029295dd3b
commit
107f0f6fa3
14 changed files with 192 additions and 142 deletions
|
@ -53,8 +53,7 @@ describe('Intro page', () => {
|
||||||
.click()
|
.click()
|
||||||
cy.get('[data-cy="version-modal"]')
|
cy.get('[data-cy="version-modal"]')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
cy.get('[data-cy="version-modal"] [data-cy="close-version-modal-button"]')
|
cy.get('[data-cy="version-modal"] .modal-header .close')
|
||||||
.contains('Close')
|
|
||||||
.click()
|
.click()
|
||||||
cy.get('[data-cy="version-modal"]')
|
cy.get('[data-cy="version-modal"]')
|
||||||
.should('not.exist')
|
.should('not.exist')
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
@ -15,14 +15,15 @@ export interface IconButtonProps extends ButtonProps {
|
||||||
icon: IconName
|
icon: IconName
|
||||||
onClick?: () => void
|
onClick?: () => void
|
||||||
border?: boolean
|
border?: boolean
|
||||||
|
iconFixedWidth?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const IconButton: React.FC<IconButtonProps> = ({ icon, children, border = false, ...props }) => {
|
export const IconButton: React.FC<IconButtonProps> = ({ icon, children, iconFixedWidth = false, border = false, className, ...props }) => {
|
||||||
return (
|
return (
|
||||||
<Button { ...props }
|
<Button { ...props }
|
||||||
className={ `btn-icon p-0 d-inline-flex align-items-stretch ${ border ? 'with-border' : '' }` }>
|
className={ `btn-icon p-0 d-inline-flex align-items-stretch ${ border ? 'with-border' : '' } ${ className ?? '' }` }>
|
||||||
<span className="icon-part d-flex align-items-center">
|
<span className="icon-part d-flex align-items-center">
|
||||||
<ForkAwesomeIcon icon={ icon } className={ 'icon' }/>
|
<ForkAwesomeIcon icon={ icon } fixedWidth={ iconFixedWidth } className={ 'icon' }/>
|
||||||
</span>
|
</span>
|
||||||
<ShowIf condition={ !!children }>
|
<ShowIf condition={ !!children }>
|
||||||
<span className="text-part d-flex align-items-center">
|
<span className="text-part d-flex align-items-center">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
@ -13,11 +13,11 @@ import { LinkWithTextProps } from './types'
|
||||||
|
|
||||||
export const InternalLink: React.FC<LinkWithTextProps> = ({ href, text, icon, id, className = 'text-light', title }) => {
|
export const InternalLink: React.FC<LinkWithTextProps> = ({ href, text, icon, id, className = 'text-light', title }) => {
|
||||||
return (
|
return (
|
||||||
<Link to={ href }
|
<Link
|
||||||
className={ className }
|
to={ href }
|
||||||
id={ id }
|
className={ className }
|
||||||
title={ title }
|
id={ id }
|
||||||
>
|
title={ title }>
|
||||||
<ShowIf condition={ !!icon }>
|
<ShowIf condition={ !!icon }>
|
||||||
<ForkAwesomeIcon icon={ icon as IconName } fixedWidth={ true }/>
|
<ForkAwesomeIcon icon={ icon as IconName } fixedWidth={ true }/>
|
||||||
</ShowIf>
|
</ShowIf>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
@ -20,13 +20,14 @@ export interface CommonModalProps {
|
||||||
icon?: IconName
|
icon?: IconName
|
||||||
size?: 'lg' | 'sm' | 'xl'
|
size?: 'lg' | 'sm' | 'xl'
|
||||||
additionalClasses?: string
|
additionalClasses?: string
|
||||||
|
'data-cy'?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CommonModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18nKey, title, closeButton, icon, additionalClasses, size, children }) => {
|
export const CommonModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18nKey, title, closeButton, icon, additionalClasses, size, children, ...props }) => {
|
||||||
useTranslation()
|
useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal data-cy={ 'limitReachedModal' } show={ show } onHide={ onHide } animation={ true }
|
<Modal data-cy={ props['data-cy'] } show={ show } onHide={ onHide } animation={ true }
|
||||||
dialogClassName={ `text-dark ${ additionalClasses ?? '' }` } size={ size }>
|
dialogClassName={ `text-dark ${ additionalClasses ?? '' }` } size={ size }>
|
||||||
<Modal.Header closeButton={ !!closeButton }>
|
<Modal.Header closeButton={ !!closeButton }>
|
||||||
<Modal.Title>
|
<Modal.Title>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings } from 'luxon'
|
import { Settings } from 'luxon'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
import { Form } from 'react-bootstrap'
|
import { Form } from 'react-bootstrap'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
@ -40,41 +40,52 @@ const languages = {
|
||||||
sk: 'Slovensky'
|
sk: 'Slovensky'
|
||||||
}
|
}
|
||||||
|
|
||||||
const findLanguageCode = (wantedLanguage: string): string => {
|
/**
|
||||||
let foundLanguage = Object.keys(languages)
|
* This function checks if the wanted language code is supported by our translations.
|
||||||
.find((supportedLanguage) => wantedLanguage === supportedLanguage)
|
* The language code that is provided by the browser can (but don't need to) contain the region.
|
||||||
if (!foundLanguage) {
|
* Some of our translations are region dependent (e.g. chinese-traditional and chinese-simplified).
|
||||||
foundLanguage = Object.keys(languages)
|
* Therefore we first need to check if the complete wanted language code is supported by our translations.
|
||||||
.find((supportedLanguage) => wantedLanguage.substr(0, 2) === supportedLanguage)
|
* If not, then we look if we at least have a region independent translation.
|
||||||
}
|
*
|
||||||
return foundLanguage || ''
|
* @param wantedLanguage an ISO 639-1 standard language code
|
||||||
}
|
*/
|
||||||
|
const findLanguageCode = (wantedLanguage: string): string => (
|
||||||
|
(
|
||||||
|
Object.keys(languages)
|
||||||
|
.find((supportedLanguage) => wantedLanguage === supportedLanguage)
|
||||||
|
) ?? (
|
||||||
|
Object.keys(languages)
|
||||||
|
.find((supportedLanguage) => wantedLanguage.substr(0, 2) === supportedLanguage)
|
||||||
|
) ?? ''
|
||||||
|
)
|
||||||
|
|
||||||
const LanguagePicker: React.FC = () => {
|
export const LanguagePicker: React.FC = () => {
|
||||||
const { i18n } = useTranslation()
|
const { i18n } = useTranslation()
|
||||||
|
|
||||||
const onChangeLang = useCallback(() => async (event: React.ChangeEvent<HTMLSelectElement>) => {
|
const onChangeLang = useCallback((event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
const language = event.currentTarget.value
|
const language = event.currentTarget.value
|
||||||
Settings.defaultLocale = language
|
Settings.defaultLocale = language
|
||||||
await i18n.changeLanguage(language)
|
i18n.changeLanguage(language)
|
||||||
|
.catch(error => console.error('Error while switching language', error))
|
||||||
}, [i18n])
|
}, [i18n])
|
||||||
|
|
||||||
|
const languageCode = useMemo(() => findLanguageCode(i18n.language), [i18n.language])
|
||||||
|
|
||||||
|
const languageOptions = useMemo(() =>
|
||||||
|
Object.entries(languages)
|
||||||
|
.map(([language, languageName]) =>
|
||||||
|
<option key={ language } value={ language }>{ languageName }</option>), [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.Control
|
<Form.Control
|
||||||
as="select"
|
as="select"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="mb-2 mx-auto w-auto"
|
className="mb-2 mx-auto w-auto"
|
||||||
value={ findLanguageCode(i18n.language) }
|
value={ languageCode }
|
||||||
onChange={ onChangeLang() }
|
onChange={ onChangeLang }>
|
||||||
>
|
|
||||||
{
|
{
|
||||||
Object.entries(languages)
|
languageOptions
|
||||||
.map(([language, languageName]) => {
|
|
||||||
return <option key={ language } value={ language }>{ languageName }</option>
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export { LanguagePicker }
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { Fragment } from 'react'
|
import React, { Fragment } from 'react'
|
||||||
|
@ -12,12 +12,13 @@ import { ApplicationState } from '../../../redux'
|
||||||
import { ExternalLink } from '../../common/links/external-link'
|
import { ExternalLink } from '../../common/links/external-link'
|
||||||
import { TranslatedExternalLink } from '../../common/links/translated-external-link'
|
import { TranslatedExternalLink } from '../../common/links/translated-external-link'
|
||||||
import { TranslatedInternalLink } from '../../common/links/translated-internal-link'
|
import { TranslatedInternalLink } from '../../common/links/translated-internal-link'
|
||||||
import { VersionInfo } from './version-info'
|
import { VersionInfoLink } from './version-info/version-info-link'
|
||||||
|
import equal from 'fast-deep-equal'
|
||||||
|
|
||||||
export const PoweredByLinks: React.FC = () => {
|
export const PoweredByLinks: React.FC = () => {
|
||||||
useTranslation()
|
useTranslation()
|
||||||
|
|
||||||
const specialLinks = useSelector((state: ApplicationState) => Object.entries(state.config.specialLinks) as [string, string][])
|
const specialLinks = useSelector((state: ApplicationState) => Object.entries(state.config.specialLinks) as [string, string][], equal)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<p>
|
<p>
|
||||||
|
@ -35,7 +36,7 @@ export const PoweredByLinks: React.FC = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
<VersionInfo/>
|
<VersionInfoLink/>
|
||||||
</p>
|
</p>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
@ -9,7 +9,7 @@ import { Trans, useTranslation } from 'react-i18next'
|
||||||
import links from '../../../links.json'
|
import links from '../../../links.json'
|
||||||
import { ExternalLink } from '../../common/links/external-link'
|
import { ExternalLink } from '../../common/links/external-link'
|
||||||
|
|
||||||
const SocialLink: React.FC = () => {
|
export const SocialLink: React.FC = () => {
|
||||||
useTranslation()
|
useTranslation()
|
||||||
return (
|
return (
|
||||||
<p>
|
<p>
|
||||||
|
@ -23,5 +23,3 @@ const SocialLink: React.FC = () => {
|
||||||
</p>
|
</p>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export { SocialLink }
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
import equal from 'fast-deep-equal'
|
|
||||||
import React, { Fragment, useState } from 'react'
|
|
||||||
import { Button, Col, Modal, Row } from 'react-bootstrap'
|
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
|
||||||
import { useSelector } from 'react-redux'
|
|
||||||
import { Link } from 'react-router-dom'
|
|
||||||
import { ApplicationState } from '../../../redux'
|
|
||||||
import frontendVersion from '../../../version.json'
|
|
||||||
import { CopyableField } from '../../common/copyable/copyable-field/copyable-field'
|
|
||||||
import { TranslatedExternalLink } from '../../common/links/translated-external-link'
|
|
||||||
import { ShowIf } from '../../common/show-if/show-if'
|
|
||||||
|
|
||||||
export const VersionInfo: React.FC = () => {
|
|
||||||
const [show, setShow] = useState(false)
|
|
||||||
|
|
||||||
const handleClose = () => setShow(false)
|
|
||||||
const handleShow = () => setShow(true)
|
|
||||||
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const serverVersion = useSelector((state: ApplicationState) => state.config.version, equal)
|
|
||||||
|
|
||||||
const column = (title: string, version: string, sourceCodeLink: string, issueTrackerLink: string) => (
|
|
||||||
<Col md={ 6 } className={ 'flex-column' }>
|
|
||||||
<h5>{ title }</h5>
|
|
||||||
<CopyableField content={ version }/>
|
|
||||||
<ShowIf condition={ !!sourceCodeLink }>
|
|
||||||
<TranslatedExternalLink i18nKey={ 'landing.versionInfo.sourceCode' }
|
|
||||||
className={ 'btn btn-sm btn-primary d-block mb-2' } href={ sourceCodeLink }/>
|
|
||||||
</ShowIf>
|
|
||||||
<ShowIf condition={ !!issueTrackerLink }>
|
|
||||||
<TranslatedExternalLink i18nKey={ 'landing.versionInfo.issueTracker' }
|
|
||||||
className={ 'btn btn-sm btn-primary d-block mb-2' } href={ issueTrackerLink }/>
|
|
||||||
</ShowIf>
|
|
||||||
</Col>
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<Link data-cy={ 'show-version-modal' } to={ '#' } className={ 'text-light' } onClick={ handleShow }>
|
|
||||||
<Trans i18nKey={ 'landing.versionInfo.versionInfo' }/>
|
|
||||||
</Link>
|
|
||||||
<Modal data-cy={ 'version-modal' } show={ show } onHide={ handleClose } animation={ true }>
|
|
||||||
<Modal.Body className="text-dark">
|
|
||||||
<h3><Trans i18nKey={ 'landing.versionInfo.title' }/></h3>
|
|
||||||
<Row>
|
|
||||||
{ column(t('landing.versionInfo.serverVersion'), serverVersion.version, serverVersion.sourceCodeUrl, serverVersion.issueTrackerUrl) }
|
|
||||||
{ column(t('landing.versionInfo.clientVersion'), frontendVersion.version, frontendVersion.sourceCodeUrl, frontendVersion.issueTrackerUrl) }
|
|
||||||
</Row>
|
|
||||||
</Modal.Body>
|
|
||||||
<Modal.Footer>
|
|
||||||
<Button variant="secondary" onClick={ handleClose } data-cy={ 'close-version-modal-button' }>
|
|
||||||
<Trans i18nKey={ 'common.close' }/>
|
|
||||||
</Button>
|
|
||||||
</Modal.Footer>
|
|
||||||
</Modal>
|
|
||||||
</Fragment>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { Fragment, useCallback, useState } from 'react'
|
||||||
|
import { Trans } from 'react-i18next'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import { VersionInfoModal } from './version-info-modal'
|
||||||
|
|
||||||
|
export const VersionInfoLink: React.FC = () => {
|
||||||
|
const [show, setShow] = useState(false)
|
||||||
|
const closeModal = useCallback(() => setShow(false), [])
|
||||||
|
const showModal = useCallback(() => setShow(true), [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<Link data-cy={ 'show-version-modal' } to={ '#' } className={ 'text-light' } onClick={ showModal }>
|
||||||
|
<Trans i18nKey={ 'landing.versionInfo.versionInfo' }/>
|
||||||
|
</Link>
|
||||||
|
<VersionInfoModal onHide={ closeModal } show={ show }/>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import Col from 'react-bootstrap/esm/Col'
|
||||||
|
import { CopyableField } from '../../../common/copyable/copyable-field/copyable-field'
|
||||||
|
import { TranslatedExternalLink } from '../../../common/links/translated-external-link'
|
||||||
|
import { ShowIf } from '../../../common/show-if/show-if'
|
||||||
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
export interface VersionInfoModalColumnProps {
|
||||||
|
titleI18nKey: string,
|
||||||
|
version: string,
|
||||||
|
sourceCodeLink: string,
|
||||||
|
issueTrackerLink: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const VersionInfoModalColumn: React.FC<VersionInfoModalColumnProps> = ({ titleI18nKey, issueTrackerLink, sourceCodeLink, version }) => {
|
||||||
|
useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Col md={ 6 } className={ 'flex-column' }>
|
||||||
|
<h5><Trans i18nKey={ titleI18nKey }/></h5>
|
||||||
|
<CopyableField content={ version }/>
|
||||||
|
<ShowIf condition={ !!sourceCodeLink }>
|
||||||
|
<TranslatedExternalLink
|
||||||
|
i18nKey={ 'landing.versionInfo.sourceCode' }
|
||||||
|
className={ 'btn btn-sm btn-primary d-block mb-2' }
|
||||||
|
href={ sourceCodeLink }/>
|
||||||
|
</ShowIf>
|
||||||
|
<ShowIf condition={ !!issueTrackerLink }>
|
||||||
|
<TranslatedExternalLink
|
||||||
|
i18nKey={ 'landing.versionInfo.issueTracker' }
|
||||||
|
className={ 'btn btn-sm btn-primary d-block mb-2' }
|
||||||
|
href={ issueTrackerLink }/>
|
||||||
|
</ShowIf>
|
||||||
|
</Col>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import { CommonModal, CommonModalProps } from '../../../common/modals/common-modal'
|
||||||
|
import { Modal, Row } from 'react-bootstrap'
|
||||||
|
import { VersionInfoModalColumn } from './version-info-modal-column'
|
||||||
|
import frontendVersion from '../../../../version.json'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
|
import { ApplicationState } from '../../../../redux'
|
||||||
|
import equal from 'fast-deep-equal'
|
||||||
|
|
||||||
|
export const VersionInfoModal: React.FC<CommonModalProps> = ({ onHide, show }) => {
|
||||||
|
const serverVersion = useSelector((state: ApplicationState) => state.config.version, equal)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CommonModal data-cy={ 'version-modal' } show={ show } onHide={ onHide } closeButton={ true }
|
||||||
|
titleI18nKey={ 'landing.versionInfo.title' }>
|
||||||
|
<Modal.Body>
|
||||||
|
<Row>
|
||||||
|
<VersionInfoModalColumn
|
||||||
|
titleI18nKey={ 'landing.versionInfo.serverVersion' }
|
||||||
|
version={ serverVersion.version }
|
||||||
|
issueTrackerLink={ serverVersion.issueTrackerUrl }
|
||||||
|
sourceCodeLink={ serverVersion.sourceCodeUrl }/>
|
||||||
|
<VersionInfoModalColumn
|
||||||
|
titleI18nKey={ 'landing.versionInfo.clientVersion' }
|
||||||
|
version={ frontendVersion.version }
|
||||||
|
issueTrackerLink={ frontendVersion.issueTrackerUrl }
|
||||||
|
sourceCodeLink={ frontendVersion.sourceCodeUrl }/>
|
||||||
|
</Row>
|
||||||
|
</Modal.Body>
|
||||||
|
</CommonModal>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
@ -19,9 +19,9 @@ export const LandingLayout: React.FC = ({ children }) => {
|
||||||
<MotdBanner/>
|
<MotdBanner/>
|
||||||
<HeaderBar/>
|
<HeaderBar/>
|
||||||
<div className={ 'd-flex flex-column justify-content-between flex-fill text-center' }>
|
<div className={ 'd-flex flex-column justify-content-between flex-fill text-center' }>
|
||||||
<div>
|
<main>
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</main>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import equal from 'fast-deep-equal'
|
import equal from 'fast-deep-equal'
|
||||||
|
@ -42,10 +42,11 @@ export const UserDropdown: React.FC = () => {
|
||||||
<Trans i18nKey="profile.userProfile"/>
|
<Trans i18nKey="profile.userProfile"/>
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
</LinkContainer>
|
</LinkContainer>
|
||||||
<Dropdown.Item dir='auto'
|
<Dropdown.Item
|
||||||
onClick={ () => {
|
dir='auto'
|
||||||
clearUser()
|
onClick={ () => {
|
||||||
} }>
|
clearUser()
|
||||||
|
} }>
|
||||||
<ForkAwesomeIcon icon="sign-out" fixedWidth={ true } className="mx-2"/>
|
<ForkAwesomeIcon icon="sign-out" fixedWidth={ true } className="mx-2"/>
|
||||||
<Trans i18nKey="login.signOut"/>
|
<Trans i18nKey="login.signOut"/>
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { FormEvent, useCallback, useState } from 'react'
|
import React, { FormEvent, useCallback, useState } from 'react'
|
||||||
|
@ -42,8 +42,7 @@ export const ViaInternal: React.FC = () => {
|
||||||
size="sm"
|
size="sm"
|
||||||
placeholder={ t('login.auth.username') }
|
placeholder={ t('login.auth.username') }
|
||||||
onChange={ (event) => setUsername(event.currentTarget.value) } className="bg-dark text-light"
|
onChange={ (event) => setUsername(event.currentTarget.value) } className="bg-dark text-light"
|
||||||
autoComplete='username'
|
autoComplete='username'/>
|
||||||
/>
|
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
|
|
||||||
<Form.Group controlId="internal-password">
|
<Form.Group controlId="internal-password">
|
||||||
|
@ -54,8 +53,7 @@ export const ViaInternal: React.FC = () => {
|
||||||
placeholder={ t('login.auth.password') }
|
placeholder={ t('login.auth.password') }
|
||||||
onChange={ (event) => setPassword(event.currentTarget.value) }
|
onChange={ (event) => setPassword(event.currentTarget.value) }
|
||||||
className="bg-dark text-light"
|
className="bg-dark text-light"
|
||||||
autoComplete='current-password'
|
autoComplete='current-password'/>
|
||||||
/>
|
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
|
|
||||||
<Alert className="small" show={ error } variant="danger">
|
<Alert className="small" show={ error } variant="danger">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue