fix: deduplicate different buttons

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-03-08 20:21:19 +01:00
parent 160f0f8297
commit aa6bd2a884
12 changed files with 44 additions and 194 deletions

View file

@ -21,8 +21,8 @@ describe('Languages', () => {
it('language changes affect the UI', () => {
cy.getByCypressId('language-picker').select('English')
cy.getByCypressId('new-note-button').find('span').contains('New note')
cy.getByCypressId('new-note-button').contains('New Note')
cy.getByCypressId('language-picker').select('Deutsch')
cy.getByCypressId('new-note-button').find('span').contains('Neue Notiz')
cy.getByCypressId('new-note-button').contains('Neue Notiz')
})
})

View file

@ -3,6 +3,9 @@
"slogan": "Der beste Weg, Notizen zu schreiben und teilen.",
"title": "Gemeinschaftliche Markdown Notizen"
},
"navigation": {
"newNote": "Neue Notiz"
},
"landing": {
"intro": {
"exploreFeatures": "Alle Funktionen",

View file

@ -8,6 +8,9 @@
"title": "Test",
"content": "It works!"
},
"navigation": {
"newNote": "New Note"
},
"renderer": {
"highlightCode": {
"copyCode": "Copy code to clipboard"

View file

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { cypressId } from '../../../utils/cypress-attribute'
import { IconButton } from '../icon-button/icon-button'
import Link from 'next/link'
import React from 'react'
import { FileEarmarkPlus as IconPlus } from 'react-bootstrap-icons'
import { Trans } from 'react-i18next'
/**
* Links to the "new note" endpoint
*/
export const NewNoteButton: React.FC = () => {
return (
<Link href={'/new'} passHref={true}>
<IconButton {...cypressId('new-note-button')} iconSize={1.5} size={'sm'} icon={IconPlus}>
<Trans i18nKey='navigation.newNote' />
</IconButton>
</Link>
)
}

View file

@ -5,13 +5,13 @@
*/
import { useApplicationState } from '../../../hooks/common/use-application-state'
import { NoteType } from '../../../redux/note-details/types/note-details'
import { NewNoteButton } from '../../common/new-note-button/new-note-button'
import { ShowIf } from '../../common/show-if/show-if'
import { SignInButton } from '../../landing-layout/navigation/sign-in-button'
import { UserDropdown } from '../../landing-layout/navigation/user-dropdown'
import { SettingsButton } from '../../layout/settings-dialog/settings-button'
import { HelpButton } from './help-button/help-button'
import { NavbarBranding } from './navbar-branding'
import { NewNoteButton } from './new-note-button'
import { ReadOnlyModeButton } from './read-only-mode-button'
import { SlideModeButton } from './slide-mode-button'
import React from 'react'
@ -49,8 +49,8 @@ export const AppBar: React.FC<AppBarProps> = ({ mode }) => {
<HelpButton />
</ShowIf>
</Nav>
<Nav className='d-flex align-items-center text-secondary justify-content-end'>
<SettingsButton className={'p-1 mx-2'} variant={'outline-dark'} />
<Nav className='d-flex gap-2 align-items-center text-secondary justify-content-end'>
<SettingsButton variant={'outline-dark'} />
<NewNoteButton />
<ShowIf condition={!userExists}>
<SignInButton size={'sm'} />

View file

@ -1,25 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { IconButton } from '../../common/icon-button/icon-button'
import Link from 'next/link'
import React from 'react'
import { Plus as IconPlus } from 'react-bootstrap-icons'
import { Trans, useTranslation } from 'react-i18next'
/**
* Renders a button to create a new note.
*/
export const NewNoteButton: React.FC = () => {
useTranslation()
return (
<Link href={'/new'} passHref={true}>
<IconButton className='mx-2' iconSize={1.5} icon={IconPlus}>
<Trans i18nKey='editor.appBar.new' />
</IconButton>
</Link>
)
}

View file

@ -5,13 +5,12 @@
*/
import { useApplicationState } from '../../../../hooks/common/use-application-state'
import { cypressId } from '../../../../utils/cypress-attribute'
import { NewNoteButton } from '../../../common/new-note-button/new-note-button'
import { SettingsButton } from '../../../layout/settings-dialog/settings-button'
import { NewGuestNoteButton } from '../new-guest-note-button'
import { NewUserNoteButton } from '../new-user-note-button'
import { SignInButton } from '../sign-in-button'
import { UserDropdown } from '../user-dropdown'
import { HeaderNavLink } from './header-nav-link'
import React, { Fragment } from 'react'
import React from 'react'
import { Navbar } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
@ -32,23 +31,10 @@ const HeaderBar: React.FC = () => {
<Trans i18nKey='landing.navigation.history' />
</HeaderNavLink>
</div>
<div className='d-inline-flex'>
<SettingsButton className={'p-1 mx-2'} variant={'outline-light'} />
{!userExists ? (
<Fragment>
<span className={'mx-1 d-flex'}>
<NewGuestNoteButton />
</span>
<SignInButton size='sm' />
</Fragment>
) : (
<Fragment>
<span className={'mx-1 d-flex'}>
<NewUserNoteButton />
</span>
<UserDropdown />
</Fragment>
)}
<div className='d-inline-flex gap-2'>
<SettingsButton variant={'outline-light'} />
<NewNoteButton />
{!userExists ? <SignInButton size='sm' /> : <UserDropdown />}
</div>
</Navbar>
)

View file

@ -1,34 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { cypressId } from '../../../utils/cypress-attribute'
import { UiIcon } from '../../common/icons/ui-icon'
import Link from 'next/link'
import React from 'react'
import { Button } from 'react-bootstrap'
import { Plus as IconPlus } from 'react-bootstrap-icons'
import { Trans, useTranslation } from 'react-i18next'
/**
* Renders a button to create a new note as a guest.
*/
export const NewGuestNoteButton: React.FC = () => {
const { t } = useTranslation()
return (
<Link href={'/new'} passHref={true}>
<Button
title={t('landing.navigation.newGuestNote') ?? undefined}
variant='primary'
size='sm'
className='d-inline-flex align-items-center'
{...cypressId('new-guest-note-button')}>
<UiIcon icon={IconPlus} className='mx-1' size={2} />
<span>
<Trans i18nKey='landing.navigation.newGuestNote' />
</span>
</Button>
</Link>
)
}

View file

@ -1,34 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { cypressId } from '../../../utils/cypress-attribute'
import { UiIcon } from '../../common/icons/ui-icon'
import Link from 'next/link'
import React from 'react'
import { Button } from 'react-bootstrap'
import { Plus as IconPlus } from 'react-bootstrap-icons'
import { Trans, useTranslation } from 'react-i18next'
/**
* Renders a button to create a new note as a logged in user.
*/
export const NewUserNoteButton: React.FC = () => {
const { t } = useTranslation()
return (
<Link href={'/new'} passHref={true}>
<Button
title={t('landing.navigation.newNote') ?? undefined}
variant='primary'
size='sm'
className='d-inline-flex align-items-center'
{...cypressId('new-note-button')}>
<UiIcon icon={IconPlus} className='mx-1' size={2} />
<span>
<Trans i18nKey='landing.navigation.newNote' />
</span>
</Button>
</Link>
)
}

View file

@ -1,27 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
.social-link-button {
&, &:hover {
color: #FFFFFF;
}
.icon-part {
padding: 0.375rem 0.375rem;
border-right: 1px solid rgba(0, 0, 0, 0.2);
display: flex;
.social-icon {
font-size: 1.5em;
}
}
.text-part {
padding: 0.375rem 0.75rem;
}
}

View file

@ -1,46 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { UiIcon } from '../../../common/icons/ui-icon'
import styles from './social-link-button.module.scss'
import type { PropsWithChildren } from 'react'
import React from 'react'
import type { Icon } from 'react-bootstrap-icons'
export interface SocialButtonProps {
backgroundClass: string
href: string
icon: Icon
title?: string
}
/**
* Renders a link for a social login.
*
* @param title The link title
* @param backgroundClass Additional classes for the a-tag
* @param href The link
* @param icon The icon to be used
* @param children The children to be rendered in addition to the icon.
*/
export const SocialLinkButton: React.FC<PropsWithChildren<SocialButtonProps>> = ({
title,
backgroundClass,
href,
icon,
children
}) => {
return (
<a
href={href}
title={title}
className={`btn ${styles['social-link-button']} p-0 d-inline-flex align-items-stretch ${backgroundClass}`}>
<span className={`${styles['icon-part']} d-flex align-items-center`}>
<UiIcon icon={icon} className={styles['social-icon']} />
</span>
<span className={`${styles['text-part']} d-flex align-items-center mx-auto`}>{children}</span>
</a>
)
}

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { AuthProvider, AuthProviderWithCustomName } from '../../../api/config/types'
import { SocialLinkButton } from './social-link-button/social-link-button'
import { IconButton } from '../../common/icon-button/icon-button'
import { getOneClickProviderMetadata } from './utils/get-one-click-provider-metadata'
import React, { useMemo } from 'react'
@ -22,8 +22,8 @@ export const ViaOneClick: React.FC<ViaOneClickProps> = ({ provider }) => {
const text = (provider as AuthProviderWithCustomName).providerName || name
return (
<SocialLinkButton backgroundClass={className} icon={icon} href={url} title={text}>
<IconButton className={className} icon={icon} href={url} title={text} border={true}>
{text}
</SocialLinkButton>
</IconButton>
)
}