mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-28 22:15:12 -04:00
Add prettier for codestyle and re-format everything (#1294)
This commit is contained in:
parent
8b78154075
commit
0aae1f70d2
319 changed files with 4809 additions and 3936 deletions
|
@ -21,20 +21,20 @@ export const Branding: React.FC<BrandingProps> = ({ inline = false, delimiter =
|
|||
const showBranding = !!branding.name || !!branding.logo
|
||||
|
||||
return (
|
||||
<ShowIf condition={ showBranding }>
|
||||
<ShowIf condition={ delimiter }>
|
||||
<strong className={ `mx-1 ${ inline ? 'inline-size' : 'regular-size' }` }>@</strong>
|
||||
<ShowIf condition={showBranding}>
|
||||
<ShowIf condition={delimiter}>
|
||||
<strong className={`mx-1 ${inline ? 'inline-size' : 'regular-size'}`}>@</strong>
|
||||
</ShowIf>
|
||||
{
|
||||
branding.logo
|
||||
? <img
|
||||
src={ branding.logo }
|
||||
alt={ branding.name }
|
||||
title={ branding.name }
|
||||
className={ inline ? 'inline-size' : 'regular-size' }
|
||||
/>
|
||||
: branding.name
|
||||
}
|
||||
{branding.logo ? (
|
||||
<img
|
||||
src={branding.logo}
|
||||
alt={branding.name}
|
||||
title={branding.name}
|
||||
className={inline ? 'inline-size' : 'regular-size'}
|
||||
/>
|
||||
) : (
|
||||
branding.name
|
||||
)}
|
||||
</ShowIf>
|
||||
)
|
||||
}
|
||||
|
|
60
src/components/common/cache/cache.test.ts
vendored
60
src/components/common/cache/cache.test.ts
vendored
|
@ -16,88 +16,68 @@ describe('Test caching functionality', () => {
|
|||
it('initialize with right lifetime, no entry limit', () => {
|
||||
const lifetime = 1000
|
||||
const lifetimedCache = new Cache<string, string>(lifetime)
|
||||
expect(lifetimedCache.entryLifetime)
|
||||
.toEqual(lifetime)
|
||||
expect(lifetimedCache.maxEntries)
|
||||
.toEqual(0)
|
||||
expect(lifetimedCache.entryLifetime).toEqual(lifetime)
|
||||
expect(lifetimedCache.maxEntries).toEqual(0)
|
||||
})
|
||||
|
||||
it('initialize with right lifetime, given entry limit', () => {
|
||||
const lifetime = 1000
|
||||
const maxEntries = 10
|
||||
const limitedCache = new Cache<string, string>(lifetime, maxEntries)
|
||||
expect(limitedCache.entryLifetime)
|
||||
.toEqual(lifetime)
|
||||
expect(limitedCache.maxEntries)
|
||||
.toEqual(maxEntries)
|
||||
expect(limitedCache.entryLifetime).toEqual(lifetime)
|
||||
expect(limitedCache.maxEntries).toEqual(maxEntries)
|
||||
})
|
||||
|
||||
it('entry exists after inserting', () => {
|
||||
testCache.put('test', 123)
|
||||
expect(testCache.has('test'))
|
||||
.toBe(true)
|
||||
expect(testCache.has('test')).toBe(true)
|
||||
})
|
||||
|
||||
it('entry does not exist prior inserting', () => {
|
||||
expect(testCache.has('test'))
|
||||
.toBe(false)
|
||||
expect(testCache.has('test')).toBe(false)
|
||||
})
|
||||
|
||||
it('entry does expire', () => {
|
||||
const shortLivingCache = new Cache<string, number>(2)
|
||||
shortLivingCache.put('test', 123)
|
||||
expect(shortLivingCache.has('test'))
|
||||
.toBe(true)
|
||||
expect(shortLivingCache.has('test')).toBe(true)
|
||||
setTimeout(() => {
|
||||
expect(shortLivingCache.has('test'))
|
||||
.toBe(false)
|
||||
expect(shortLivingCache.has('test')).toBe(false)
|
||||
}, 2000)
|
||||
})
|
||||
|
||||
it('entry value does not change', () => {
|
||||
const testValue = Date.now()
|
||||
testCache.put('test', testValue)
|
||||
expect(testCache.get('test'))
|
||||
.toEqual(testValue)
|
||||
expect(testCache.get('test')).toEqual(testValue)
|
||||
})
|
||||
|
||||
it('error is thrown on non-existent entry', () => {
|
||||
const accessNonExistentEntry = () => {
|
||||
testCache.get('test')
|
||||
}
|
||||
expect(accessNonExistentEntry)
|
||||
.toThrow(Error)
|
||||
expect(accessNonExistentEntry).toThrow(Error)
|
||||
})
|
||||
|
||||
it('newer item replaces older item', () => {
|
||||
testCache.put('test', 123)
|
||||
testCache.put('test', 456)
|
||||
expect(testCache.get('test'))
|
||||
.toEqual(456)
|
||||
expect(testCache.get('test')).toEqual(456)
|
||||
})
|
||||
|
||||
it('entry limit is respected', () => {
|
||||
const limitedCache = new Cache<string, number>(1000, 2)
|
||||
limitedCache.put('first', 1)
|
||||
expect(limitedCache.has('first'))
|
||||
.toBe(true)
|
||||
expect(limitedCache.has('second'))
|
||||
.toBe(false)
|
||||
expect(limitedCache.has('third'))
|
||||
.toBe(false)
|
||||
expect(limitedCache.has('first')).toBe(true)
|
||||
expect(limitedCache.has('second')).toBe(false)
|
||||
expect(limitedCache.has('third')).toBe(false)
|
||||
limitedCache.put('second', 2)
|
||||
expect(limitedCache.has('first'))
|
||||
.toBe(true)
|
||||
expect(limitedCache.has('second'))
|
||||
.toBe(true)
|
||||
expect(limitedCache.has('third'))
|
||||
.toBe(false)
|
||||
expect(limitedCache.has('first')).toBe(true)
|
||||
expect(limitedCache.has('second')).toBe(true)
|
||||
expect(limitedCache.has('third')).toBe(false)
|
||||
limitedCache.put('third', 3)
|
||||
expect(limitedCache.has('first'))
|
||||
.toBe(false)
|
||||
expect(limitedCache.has('second'))
|
||||
.toBe(true)
|
||||
expect(limitedCache.has('third'))
|
||||
.toBe(true)
|
||||
expect(limitedCache.has('first')).toBe(false)
|
||||
expect(limitedCache.has('second')).toBe(true)
|
||||
expect(limitedCache.has('third')).toBe(true)
|
||||
})
|
||||
})
|
||||
|
|
5
src/components/common/cache/cache.ts
vendored
5
src/components/common/cache/cache.ts
vendored
|
@ -27,7 +27,7 @@ export class Cache<K, V> {
|
|||
return false
|
||||
}
|
||||
const entry = this.store.get(key)
|
||||
return (!!entry && entry.entryCreated >= (Date.now() - this.entryLifetime * 1000))
|
||||
return !!entry && entry.entryCreated >= Date.now() - this.entryLifetime * 1000
|
||||
}
|
||||
|
||||
get(key: K): V {
|
||||
|
@ -40,8 +40,7 @@ export class Cache<K, V> {
|
|||
|
||||
put(key: K, value: V): void {
|
||||
if (this.maxEntries > 0 && this.store.size === this.maxEntries) {
|
||||
this.store.delete(this.store.keys()
|
||||
.next().value)
|
||||
this.store.delete(this.store.keys().next().value)
|
||||
}
|
||||
this.store.set(key, {
|
||||
entryCreated: Date.now(),
|
||||
|
|
|
@ -22,20 +22,21 @@ export const CopyOverlay: React.FC<CopyOverlayProps> = ({ content, clickComponen
|
|||
const [tooltipId] = useState<string>(() => uuid())
|
||||
|
||||
const copyToClipboard = useCallback((content: string) => {
|
||||
navigator.clipboard.writeText(content)
|
||||
.then(() => {
|
||||
setError(false)
|
||||
})
|
||||
.catch(() => {
|
||||
setError(true)
|
||||
console.error('couldn\'t copy')
|
||||
})
|
||||
.finally(() => {
|
||||
setShowCopiedTooltip(true)
|
||||
setTimeout(() => {
|
||||
setShowCopiedTooltip(false)
|
||||
}, 2000)
|
||||
})
|
||||
navigator.clipboard
|
||||
.writeText(content)
|
||||
.then(() => {
|
||||
setError(false)
|
||||
})
|
||||
.catch(() => {
|
||||
setError(true)
|
||||
console.error("couldn't copy")
|
||||
})
|
||||
.finally(() => {
|
||||
setShowCopiedTooltip(true)
|
||||
setTimeout(() => {
|
||||
setShowCopiedTooltip(false)
|
||||
}, 2000)
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -51,17 +52,17 @@ export const CopyOverlay: React.FC<CopyOverlayProps> = ({ content, clickComponen
|
|||
}, [clickComponent, copyToClipboard, content])
|
||||
|
||||
return (
|
||||
<Overlay target={ clickComponent } show={ showCopiedTooltip } placement="top">
|
||||
{ (props) => (
|
||||
<Tooltip id={ `copied_${ tooltipId }` } { ...props }>
|
||||
<ShowIf condition={ error }>
|
||||
<Trans i18nKey={ 'common.copyError' }/>
|
||||
<Overlay target={clickComponent} show={showCopiedTooltip} placement='top'>
|
||||
{(props) => (
|
||||
<Tooltip id={`copied_${tooltipId}`} {...props}>
|
||||
<ShowIf condition={error}>
|
||||
<Trans i18nKey={'common.copyError'} />
|
||||
</ShowIf>
|
||||
<ShowIf condition={ !error }>
|
||||
<Trans i18nKey={ 'common.successfullyCopied' }/>
|
||||
<ShowIf condition={!error}>
|
||||
<Trans i18nKey={'common.successfullyCopied'} />
|
||||
</ShowIf>
|
||||
</Tooltip>
|
||||
) }
|
||||
)}
|
||||
</Overlay>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -29,11 +29,15 @@ export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({
|
|||
|
||||
return (
|
||||
<Fragment>
|
||||
<Button ref={ button } size={ size } variant={ variant } title={ t('renderer.highlightCode.copyCode') }
|
||||
data-cy={ props['data-cy'] }>
|
||||
<ForkAwesomeIcon icon='files-o'/>
|
||||
<Button
|
||||
ref={button}
|
||||
size={size}
|
||||
variant={variant}
|
||||
title={t('renderer.highlightCode.copyCode')}
|
||||
data-cy={props['data-cy']}>
|
||||
<ForkAwesomeIcon icon='files-o' />
|
||||
</Button>
|
||||
<CopyOverlay content={ content } clickComponent={ button }/>
|
||||
<CopyOverlay content={content} clickComponent={button} />
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -22,35 +22,36 @@ export const CopyableField: React.FC<CopyableFieldProps> = ({ content, nativeSha
|
|||
const copyButton = useRef<HTMLButtonElement>(null)
|
||||
|
||||
const doShareAction = useCallback(() => {
|
||||
navigator.share({
|
||||
text: content,
|
||||
url: url
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Native sharing failed: ', err)
|
||||
})
|
||||
navigator
|
||||
.share({
|
||||
text: content,
|
||||
url: url
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Native sharing failed: ', err)
|
||||
})
|
||||
}, [content, url])
|
||||
|
||||
const sharingSupported = typeof navigator.share === 'function'
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<InputGroup className="my-3">
|
||||
<FormControl readOnly={ true } className={ 'text-center' } value={ content }/>
|
||||
<InputGroup className='my-3'>
|
||||
<FormControl readOnly={true} className={'text-center'} value={content} />
|
||||
<InputGroup.Append>
|
||||
<Button variant="outline-secondary" ref={ copyButton } title={ 'Copy' }>
|
||||
<ForkAwesomeIcon icon='files-o'/>
|
||||
<Button variant='outline-secondary' ref={copyButton} title={'Copy'}>
|
||||
<ForkAwesomeIcon icon='files-o' />
|
||||
</Button>
|
||||
</InputGroup.Append>
|
||||
<ShowIf condition={ !!nativeShareButton && sharingSupported }>
|
||||
<ShowIf condition={!!nativeShareButton && sharingSupported}>
|
||||
<InputGroup.Append>
|
||||
<Button variant="outline-secondary" title={ 'Share' } onClick={ doShareAction }>
|
||||
<ForkAwesomeIcon icon='share-alt'/>
|
||||
<Button variant='outline-secondary' title={'Share'} onClick={doShareAction}>
|
||||
<ForkAwesomeIcon icon='share-alt' />
|
||||
</Button>
|
||||
</InputGroup.Append>
|
||||
</ShowIf>
|
||||
</InputGroup>
|
||||
<CopyOverlay content={ content } clickComponent={ copyButton }/>
|
||||
<CopyOverlay content={content} clickComponent={copyButton} />
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -15,12 +15,16 @@ export interface ForkAwesomeIconProps {
|
|||
stacked?: boolean
|
||||
}
|
||||
|
||||
export const ForkAwesomeIcon: React.FC<ForkAwesomeIconProps> = ({ icon, fixedWidth = false, size, className, stacked = false }) => {
|
||||
export const ForkAwesomeIcon: React.FC<ForkAwesomeIconProps> = ({
|
||||
icon,
|
||||
fixedWidth = false,
|
||||
size,
|
||||
className,
|
||||
stacked = false
|
||||
}) => {
|
||||
const fixedWithClass = fixedWidth ? 'fa-fw' : ''
|
||||
const sizeClass = size ? `-${ size }` : (stacked ? '-1x' : '')
|
||||
const sizeClass = size ? `-${size}` : stacked ? '-1x' : ''
|
||||
const stackClass = stacked ? '-stack' : ''
|
||||
const extraClasses = `${ className ?? '' } ${ sizeClass || stackClass ? `fa${ stackClass }${ sizeClass }` : '' }`
|
||||
return (
|
||||
<i className={ `fa ${ fixedWithClass } fa-${ icon } ${ extraClasses }` }/>
|
||||
)
|
||||
const extraClasses = `${className ?? ''} ${sizeClass || stackClass ? `fa${stackClass}${sizeClass}` : ''}`
|
||||
return <i className={`fa ${fixedWithClass} fa-${icon} ${extraClasses}`} />
|
||||
}
|
||||
|
|
|
@ -15,15 +15,13 @@ export interface ForkAwesomeStackProps {
|
|||
|
||||
export const ForkAwesomeStack: React.FC<ForkAwesomeStackProps> = ({ size, children }) => {
|
||||
return (
|
||||
<span className={ `fa-stack ${ size ? 'fa-' : '' }${ size ?? '' }` }>
|
||||
{
|
||||
React.Children.map(children, (child) => {
|
||||
if (!React.isValidElement<ForkAwesomeIconProps>(child)) {
|
||||
return null
|
||||
}
|
||||
return <ForkAwesomeIcon { ...child.props } stacked={ true }/>
|
||||
})
|
||||
}
|
||||
<span className={`fa-stack ${size ? 'fa-' : ''}${size ?? ''}`}>
|
||||
{React.Children.map(children, (child) => {
|
||||
if (!React.isValidElement<ForkAwesomeIconProps>(child)) {
|
||||
return null
|
||||
}
|
||||
return <ForkAwesomeIcon {...child.props} stacked={true} />
|
||||
})}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ export enum HedgeDocLogoSize {
|
|||
}
|
||||
|
||||
export interface HedgeDocLogoProps {
|
||||
size?: HedgeDocLogoSize | number,
|
||||
size?: HedgeDocLogoSize | number
|
||||
logoType: HedgeDocLogoType
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,11 @@ export enum HedgeDocLogoType {
|
|||
export const HedgeDocLogoWithText: React.FC<HedgeDocLogoProps> = ({ size = HedgeDocLogoSize.MEDIUM, logoType }) => {
|
||||
switch (logoType) {
|
||||
case HedgeDocLogoType.COLOR_VERTICAL:
|
||||
return <LogoColorVertical className={ 'w-auto' } title={ 'HedgeDoc logo with text' } style={ { height: size } }/>
|
||||
return <LogoColorVertical className={'w-auto'} title={'HedgeDoc logo with text'} style={{ height: size }} />
|
||||
case HedgeDocLogoType.BW_HORIZONTAL:
|
||||
return <LogoBwHorizontal className={ 'w-auto' } title={ 'HedgeDoc logo with text' } style={ { height: size } }/>
|
||||
return <LogoBwHorizontal className={'w-auto'} title={'HedgeDoc logo with text'} style={{ height: size }} />
|
||||
case HedgeDocLogoType.WB_HORIZONTAL:
|
||||
return <LogoWbHorizontal className={ 'w-auto' } title={ 'HedgeDoc logo with text' } style={ { height: size } }/>
|
||||
return <LogoWbHorizontal className={'w-auto'} title={'HedgeDoc logo with text'} style={{ height: size }} />
|
||||
default:
|
||||
return null
|
||||
}
|
||||
|
|
|
@ -18,5 +18,5 @@ export interface HedgeDocLogoProps {
|
|||
}
|
||||
|
||||
export const HedgeDocLogo: React.FC<HedgeDocLogoProps> = ({ size = HedgeDocLogoSize.MEDIUM }) => {
|
||||
return <LogoColor className={ 'w-auto' } title={ 'HedgeDoc logo with text' } style={ { height: size } }/>
|
||||
return <LogoColor className={'w-auto'} title={'HedgeDoc logo with text'} style={{ height: size }} />
|
||||
}
|
||||
|
|
|
@ -18,17 +18,23 @@ export interface IconButtonProps extends ButtonProps {
|
|||
iconFixedWidth?: boolean
|
||||
}
|
||||
|
||||
export const IconButton: React.FC<IconButtonProps> = ({ icon, children, iconFixedWidth = false, border = false, className, ...props }) => {
|
||||
export const IconButton: React.FC<IconButtonProps> = ({
|
||||
icon,
|
||||
children,
|
||||
iconFixedWidth = false,
|
||||
border = false,
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<Button { ...props }
|
||||
className={ `btn-icon p-0 d-inline-flex align-items-stretch ${ border ? 'with-border' : '' } ${ className ?? '' }` }>
|
||||
<span className="icon-part d-flex align-items-center">
|
||||
<ForkAwesomeIcon icon={ icon } fixedWidth={ iconFixedWidth } className={ 'icon' }/>
|
||||
<Button
|
||||
{...props}
|
||||
className={`btn-icon p-0 d-inline-flex align-items-stretch ${border ? 'with-border' : ''} ${className ?? ''}`}>
|
||||
<span className='icon-part d-flex align-items-center'>
|
||||
<ForkAwesomeIcon icon={icon} fixedWidth={iconFixedWidth} className={'icon'} />
|
||||
</span>
|
||||
<ShowIf condition={ !!children }>
|
||||
<span className="text-part d-flex align-items-center">
|
||||
{ children }
|
||||
</span>
|
||||
<ShowIf condition={!!children}>
|
||||
<span className='text-part d-flex align-items-center'>{children}</span>
|
||||
</ShowIf>
|
||||
</Button>
|
||||
)
|
||||
|
|
|
@ -14,8 +14,8 @@ export interface TranslatedIconButtonProps extends IconButtonProps {
|
|||
|
||||
export const TranslatedIconButton: React.FC<TranslatedIconButtonProps> = ({ i18nKey, ...props }) => {
|
||||
return (
|
||||
<IconButton { ...props }>
|
||||
<Trans i18nKey={ i18nKey }/>
|
||||
<IconButton {...props}>
|
||||
<Trans i18nKey={i18nKey} />
|
||||
</IconButton>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -10,20 +10,21 @@ import { IconName } from '../fork-awesome/types'
|
|||
import { ShowIf } from '../show-if/show-if'
|
||||
import { LinkWithTextProps } from './types'
|
||||
|
||||
export const ExternalLink: React.FC<LinkWithTextProps> = ({ href, text, icon, id, className = 'text-light', title }) => {
|
||||
export const ExternalLink: React.FC<LinkWithTextProps> = ({
|
||||
href,
|
||||
text,
|
||||
icon,
|
||||
id,
|
||||
className = 'text-light',
|
||||
title
|
||||
}) => {
|
||||
return (
|
||||
<a href={ href }
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
id={ id }
|
||||
className={ className }
|
||||
title={ title }
|
||||
dir='auto'
|
||||
>
|
||||
<ShowIf condition={ !!icon }>
|
||||
<ForkAwesomeIcon icon={ icon as IconName } fixedWidth={ true }/>
|
||||
<a href={href} target='_blank' rel='noopener noreferrer' id={id} className={className} title={title} dir='auto'>
|
||||
<ShowIf condition={!!icon}>
|
||||
<ForkAwesomeIcon icon={icon as IconName} fixedWidth={true} />
|
||||
|
||||
</ShowIf>
|
||||
{ text }
|
||||
{text}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,17 +11,21 @@ import { IconName } from '../fork-awesome/types'
|
|||
import { ShowIf } from '../show-if/show-if'
|
||||
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 (
|
||||
<Link
|
||||
to={ href }
|
||||
className={ className }
|
||||
id={ id }
|
||||
title={ title }>
|
||||
<ShowIf condition={ !!icon }>
|
||||
<ForkAwesomeIcon icon={ icon as IconName } fixedWidth={ true }/>
|
||||
<Link to={href} className={className} id={id} title={title}>
|
||||
<ShowIf condition={!!icon}>
|
||||
<ForkAwesomeIcon icon={icon as IconName} fixedWidth={true} />
|
||||
|
||||
</ShowIf>
|
||||
{ text }
|
||||
{text}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,5 @@ import { TranslatedLinkProps } from './types'
|
|||
|
||||
export const TranslatedExternalLink: React.FC<TranslatedLinkProps> = ({ i18nKey, i18nOption, ...props }) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<ExternalLink text={ t(i18nKey, i18nOption) } { ...props }/>
|
||||
)
|
||||
return <ExternalLink text={t(i18nKey, i18nOption)} {...props} />
|
||||
}
|
||||
|
|
|
@ -11,7 +11,5 @@ import { TranslatedLinkProps } from './types'
|
|||
|
||||
export const TranslatedInternalLink: React.FC<TranslatedLinkProps> = ({ i18nKey, i18nOption, ...props }) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<InternalLink text={ t(i18nKey, i18nOption) } { ...props }/>
|
||||
)
|
||||
return <InternalLink text={t(i18nKey, i18nOption)} {...props} />
|
||||
}
|
||||
|
|
|
@ -9,18 +9,15 @@ import { Button } from 'react-bootstrap'
|
|||
import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon'
|
||||
|
||||
export interface LockButtonProps {
|
||||
locked: boolean,
|
||||
locked: boolean
|
||||
onLockedChanged: (newState: boolean) => void
|
||||
title: string
|
||||
}
|
||||
|
||||
export const LockButton: React.FC<LockButtonProps> = ({ locked, onLockedChanged, title }) => {
|
||||
return (
|
||||
<Button variant='dark' size='sm' onClick={ () => onLockedChanged(!locked) } title={ title }>
|
||||
{ locked
|
||||
? <ForkAwesomeIcon icon='lock'/>
|
||||
: <ForkAwesomeIcon icon='unlock'/>
|
||||
}
|
||||
<Button variant='dark' size='sm' onClick={() => onLockedChanged(!locked)} title={title}>
|
||||
{locked ? <ForkAwesomeIcon icon='lock' /> : <ForkAwesomeIcon icon='unlock' />}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -23,24 +23,38 @@ export interface CommonModalProps {
|
|||
'data-cy'?: string
|
||||
}
|
||||
|
||||
export const CommonModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18nKey, title, closeButton, icon, additionalClasses, size, children, ...props }) => {
|
||||
export const CommonModal: React.FC<CommonModalProps> = ({
|
||||
show,
|
||||
onHide,
|
||||
titleI18nKey,
|
||||
title,
|
||||
closeButton,
|
||||
icon,
|
||||
additionalClasses,
|
||||
size,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
useTranslation()
|
||||
|
||||
return (
|
||||
<Modal data-cy={ props['data-cy'] } show={ show } onHide={ onHide } animation={ true }
|
||||
dialogClassName={ `text-dark ${ additionalClasses ?? '' }` } size={ size }>
|
||||
<Modal.Header closeButton={ !!closeButton }>
|
||||
<Modal
|
||||
data-cy={props['data-cy']}
|
||||
show={show}
|
||||
onHide={onHide}
|
||||
animation={true}
|
||||
dialogClassName={`text-dark ${additionalClasses ?? ''}`}
|
||||
size={size}>
|
||||
<Modal.Header closeButton={!!closeButton}>
|
||||
<Modal.Title>
|
||||
<ShowIf condition={ !!icon }>
|
||||
<ForkAwesomeIcon icon={ icon as IconName }/>
|
||||
<ShowIf condition={!!icon}>
|
||||
<ForkAwesomeIcon icon={icon as IconName} />
|
||||
|
||||
</ShowIf>
|
||||
{ titleI18nKey
|
||||
? <Trans i18nKey={ titleI18nKey }/>
|
||||
: <span>{ title }</span>
|
||||
}
|
||||
{titleI18nKey ? <Trans i18nKey={titleI18nKey} /> : <span>{title}</span>}
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
{ children }
|
||||
{children}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,17 +14,23 @@ export interface DeletionModalProps extends CommonModalProps {
|
|||
deletionButtonI18nKey: string
|
||||
}
|
||||
|
||||
export const DeletionModal: React.FC<DeletionModalProps> = ({ show, onHide, titleI18nKey, onConfirm, deletionButtonI18nKey, icon, children }) => {
|
||||
export const DeletionModal: React.FC<DeletionModalProps> = ({
|
||||
show,
|
||||
onHide,
|
||||
titleI18nKey,
|
||||
onConfirm,
|
||||
deletionButtonI18nKey,
|
||||
icon,
|
||||
children
|
||||
}) => {
|
||||
useTranslation()
|
||||
|
||||
return (
|
||||
<CommonModal show={ show } onHide={ onHide } titleI18nKey={ titleI18nKey } icon={ icon } closeButton={ true }>
|
||||
<Modal.Body className="text-dark">
|
||||
{ children }
|
||||
</Modal.Body>
|
||||
<CommonModal show={show} onHide={onHide} titleI18nKey={titleI18nKey} icon={icon} closeButton={true}>
|
||||
<Modal.Body className='text-dark'>{children}</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant="danger" onClick={ onConfirm }>
|
||||
<Trans i18nKey={ deletionButtonI18nKey }/>
|
||||
<Button variant='danger' onClick={onConfirm}>
|
||||
<Trans i18nKey={deletionButtonI18nKey} />
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</CommonModal>
|
||||
|
|
|
@ -10,10 +10,8 @@ import { CommonModal, CommonModalProps } from './common-modal'
|
|||
|
||||
export const ErrorModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18nKey, icon, children }) => {
|
||||
return (
|
||||
<CommonModal show={ show } onHide={ onHide } titleI18nKey={ titleI18nKey } icon={ icon } closeButton={ true }>
|
||||
<Modal.Body className="text-dark text-center">
|
||||
{ children }
|
||||
</Modal.Body>
|
||||
<CommonModal show={show} onHide={onHide} titleI18nKey={titleI18nKey} icon={icon} closeButton={true}>
|
||||
<Modal.Body className='text-dark text-center'>{children}</Modal.Body>
|
||||
</CommonModal>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -31,22 +31,18 @@ export const MotdBanner: React.FC = () => {
|
|||
}
|
||||
|
||||
if (!bannerState.text) {
|
||||
return <span data-cy={ 'no-motd-banner' }/>
|
||||
return <span data-cy={'no-motd-banner'} />
|
||||
}
|
||||
|
||||
return (
|
||||
<Alert data-cy={ 'motd-banner' } variant="primary" dir="auto"
|
||||
className="mb-0 text-center d-flex flex-row justify-content-center">
|
||||
<span className="flex-grow-1 align-self-center text-black">
|
||||
{ bannerState.text }
|
||||
</span>
|
||||
<Button
|
||||
data-cy={ 'motd-dismiss' }
|
||||
variant="outline-primary"
|
||||
size="sm"
|
||||
className="mx-2"
|
||||
onClick={ dismissBanner }>
|
||||
<ForkAwesomeIcon icon="times"/>
|
||||
<Alert
|
||||
data-cy={'motd-banner'}
|
||||
variant='primary'
|
||||
dir='auto'
|
||||
className='mb-0 text-center d-flex flex-row justify-content-center'>
|
||||
<span className='flex-grow-1 align-self-center text-black'>{bannerState.text}</span>
|
||||
<Button data-cy={'motd-dismiss'} variant='outline-primary' size='sm' className='mx-2' onClick={dismissBanner}>
|
||||
<ForkAwesomeIcon icon='times' />
|
||||
</Button>
|
||||
</Alert>
|
||||
)
|
||||
|
|
|
@ -5,6 +5,5 @@
|
|||
*/
|
||||
|
||||
export const createNumberRangeArray = (length: number): number[] => {
|
||||
return Array.from(Array(length)
|
||||
.keys())
|
||||
return Array.from(Array(length).keys())
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@ export interface PageItemProps {
|
|||
|
||||
export const PagerItem: React.FC<PageItemProps> = ({ index, onClick }) => {
|
||||
return (
|
||||
<li className="page-item">
|
||||
<span className="page-link" role="button" onClick={ () => onClick(index) }>
|
||||
{ index + 1 }
|
||||
<li className='page-item'>
|
||||
<span className='page-link' role='button' onClick={() => onClick(index)}>
|
||||
{index + 1}
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
|
|
|
@ -15,7 +15,11 @@ export interface PaginationProps {
|
|||
lastPageIndex: number
|
||||
}
|
||||
|
||||
export const PagerPagination: React.FC<PaginationProps> = ({ numberOfPageButtonsToShowAfterAndBeforeCurrent, onPageChange, lastPageIndex }) => {
|
||||
export const PagerPagination: React.FC<PaginationProps> = ({
|
||||
numberOfPageButtonsToShowAfterAndBeforeCurrent,
|
||||
onPageChange,
|
||||
lastPageIndex
|
||||
}) => {
|
||||
if (numberOfPageButtonsToShowAfterAndBeforeCurrent % 2 !== 0) {
|
||||
throw new Error('number of pages to show must be even!')
|
||||
}
|
||||
|
@ -29,55 +33,38 @@ export const PagerPagination: React.FC<PaginationProps> = ({ numberOfPageButtons
|
|||
onPageChange(pageIndex)
|
||||
}, [onPageChange, pageIndex])
|
||||
|
||||
const correctedLowerPageIndex =
|
||||
Math.min(
|
||||
Math.max(
|
||||
Math.min(
|
||||
wantedLowerPageIndex,
|
||||
wantedLowerPageIndex + lastPageIndex - wantedUpperPageIndex
|
||||
),
|
||||
0
|
||||
),
|
||||
lastPageIndex
|
||||
)
|
||||
const correctedLowerPageIndex = Math.min(
|
||||
Math.max(Math.min(wantedLowerPageIndex, wantedLowerPageIndex + lastPageIndex - wantedUpperPageIndex), 0),
|
||||
lastPageIndex
|
||||
)
|
||||
|
||||
const correctedUpperPageIndex =
|
||||
Math.max(
|
||||
Math.min(
|
||||
Math.max(
|
||||
wantedUpperPageIndex,
|
||||
wantedUpperPageIndex - wantedLowerPageIndex
|
||||
),
|
||||
lastPageIndex
|
||||
),
|
||||
0
|
||||
)
|
||||
const correctedUpperPageIndex = Math.max(
|
||||
Math.min(Math.max(wantedUpperPageIndex, wantedUpperPageIndex - wantedLowerPageIndex), lastPageIndex),
|
||||
0
|
||||
)
|
||||
|
||||
const paginationItemsBefore = Array.from(new Array(correctedPageIndex - correctedLowerPageIndex))
|
||||
.map((k, index) => {
|
||||
const itemIndex = correctedLowerPageIndex + index
|
||||
return <PagerItem key={ itemIndex } index={ itemIndex }
|
||||
onClick={ setPageIndex }/>
|
||||
})
|
||||
const paginationItemsBefore = Array.from(new Array(correctedPageIndex - correctedLowerPageIndex)).map((k, index) => {
|
||||
const itemIndex = correctedLowerPageIndex + index
|
||||
return <PagerItem key={itemIndex} index={itemIndex} onClick={setPageIndex} />
|
||||
})
|
||||
|
||||
const paginationItemsAfter = Array.from(new Array(correctedUpperPageIndex - correctedPageIndex))
|
||||
.map((k, index) => {
|
||||
const itemIndex = correctedPageIndex + index + 1
|
||||
return <PagerItem key={ itemIndex } index={ itemIndex } onClick={ setPageIndex }/>
|
||||
})
|
||||
const paginationItemsAfter = Array.from(new Array(correctedUpperPageIndex - correctedPageIndex)).map((k, index) => {
|
||||
const itemIndex = correctedPageIndex + index + 1
|
||||
return <PagerItem key={itemIndex} index={itemIndex} onClick={setPageIndex} />
|
||||
})
|
||||
|
||||
return (
|
||||
<Pagination dir='ltr'>
|
||||
<ShowIf condition={ correctedLowerPageIndex > 0 }>
|
||||
<PagerItem key={ 0 } index={ 0 } onClick={ setPageIndex }/>
|
||||
<Pagination.Ellipsis disabled/>
|
||||
<ShowIf condition={correctedLowerPageIndex > 0}>
|
||||
<PagerItem key={0} index={0} onClick={setPageIndex} />
|
||||
<Pagination.Ellipsis disabled />
|
||||
</ShowIf>
|
||||
{ paginationItemsBefore }
|
||||
<Pagination.Item active>{ correctedPageIndex + 1 }</Pagination.Item>
|
||||
{ paginationItemsAfter }
|
||||
<ShowIf condition={ correctedUpperPageIndex < lastPageIndex }>
|
||||
<Pagination.Ellipsis disabled/>
|
||||
<PagerItem key={ lastPageIndex } index={ lastPageIndex } onClick={ setPageIndex }/>
|
||||
{paginationItemsBefore}
|
||||
<Pagination.Item active>{correctedPageIndex + 1}</Pagination.Item>
|
||||
{paginationItemsAfter}
|
||||
<ShowIf condition={correctedUpperPageIndex < lastPageIndex}>
|
||||
<Pagination.Ellipsis disabled />
|
||||
<PagerItem key={lastPageIndex} index={lastPageIndex} onClick={setPageIndex} />
|
||||
</ShowIf>
|
||||
</Pagination>
|
||||
)
|
||||
|
|
|
@ -12,7 +12,12 @@ export interface PagerPageProps {
|
|||
onLastPageIndexChange: (lastPageIndex: number) => void
|
||||
}
|
||||
|
||||
export const Pager: React.FC<PagerPageProps> = ({ children, numberOfElementsPerPage, pageIndex, onLastPageIndexChange }) => {
|
||||
export const Pager: React.FC<PagerPageProps> = ({
|
||||
children,
|
||||
numberOfElementsPerPage,
|
||||
pageIndex,
|
||||
onLastPageIndexChange
|
||||
}) => {
|
||||
const maxPageIndex = Math.ceil(React.Children.count(children) / numberOfElementsPerPage) - 1
|
||||
const correctedPageIndex = Math.min(maxPageIndex, Math.max(0, pageIndex))
|
||||
|
||||
|
@ -20,13 +25,12 @@ export const Pager: React.FC<PagerPageProps> = ({ children, numberOfElementsPerP
|
|||
onLastPageIndexChange(maxPageIndex)
|
||||
}, [children, maxPageIndex, numberOfElementsPerPage, onLastPageIndexChange])
|
||||
|
||||
return <Fragment>
|
||||
{
|
||||
React.Children.toArray(children)
|
||||
.filter((value, index) => {
|
||||
const pageOfElement = Math.floor((index) / numberOfElementsPerPage)
|
||||
return (pageOfElement === correctedPageIndex)
|
||||
})
|
||||
}
|
||||
</Fragment>
|
||||
return (
|
||||
<Fragment>
|
||||
{React.Children.toArray(children).filter((value, index) => {
|
||||
const pageOfElement = Math.floor(index / numberOfElementsPerPage)
|
||||
return pageOfElement === correctedPageIndex
|
||||
})}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@ export const NotFoundErrorScreen: React.FC = () => {
|
|||
return (
|
||||
<LandingLayout>
|
||||
<div className='text-light d-flex align-items-center justify-content-center my-5'>
|
||||
<h1>404 Not Found <small>oops.</small></h1>
|
||||
<h1>
|
||||
404 Not Found <small>oops.</small>
|
||||
</h1>
|
||||
</div>
|
||||
</LandingLayout>
|
||||
)
|
||||
|
|
|
@ -26,10 +26,10 @@ export const Redirector: React.FC = () => {
|
|||
}, [id])
|
||||
|
||||
if (error) {
|
||||
return (<NotFoundErrorScreen/>)
|
||||
return <NotFoundErrorScreen />
|
||||
} else if (!error && error != null) {
|
||||
return (<Redirect to={ `/n/${ id }` }/>)
|
||||
return <Redirect to={`/n/${id}`} />
|
||||
} else {
|
||||
return (<span>Loading</span>)
|
||||
return <span>Loading</span>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,5 +11,5 @@ export interface ShowIfProps {
|
|||
}
|
||||
|
||||
export const ShowIf: React.FC<ShowIfProps> = ({ children, condition }) => {
|
||||
return condition ? <Fragment>{ children }</Fragment> : null
|
||||
return condition ? <Fragment>{children}</Fragment> : null
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ import './user-avatar.scss'
|
|||
|
||||
export interface UserAvatarProps {
|
||||
size?: 'sm' | 'lg'
|
||||
name: string;
|
||||
photo: string;
|
||||
additionalClasses?: string;
|
||||
name: string
|
||||
photo: string
|
||||
additionalClasses?: string
|
||||
showName?: boolean
|
||||
}
|
||||
|
||||
|
@ -21,15 +21,15 @@ const UserAvatar: React.FC<UserAvatarProps> = ({ name, photo, size, additionalCl
|
|||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<span className={ 'd-inline-flex align-items-center ' + additionalClasses }>
|
||||
<span className={'d-inline-flex align-items-center ' + additionalClasses}>
|
||||
<img
|
||||
src={ photo }
|
||||
className={ `user-avatar rounded mr-1 ${ size ?? '' }` }
|
||||
alt={ t('common.avatarOf', { name }) }
|
||||
title={ name }
|
||||
src={photo}
|
||||
className={`user-avatar rounded mr-1 ${size ?? ''}`}
|
||||
alt={t('common.avatarOf', { name })}
|
||||
title={name}
|
||||
/>
|
||||
<ShowIf condition={ showName }>
|
||||
<span className="mx-1 user-line-name">{ name }</span>
|
||||
<ShowIf condition={showName}>
|
||||
<span className='mx-1 user-line-name'>{name}</span>
|
||||
</ShowIf>
|
||||
</span>
|
||||
)
|
||||
|
|
|
@ -9,8 +9,8 @@ import { ForkAwesomeIcon } from '../fork-awesome/fork-awesome-icon'
|
|||
|
||||
export const WaitSpinner: React.FC = () => {
|
||||
return (
|
||||
<div className={ 'm-3 d-flex align-items-center justify-content-center' }>
|
||||
<ForkAwesomeIcon icon={ 'spinner' } className={ 'fa-spin' }/>
|
||||
<div className={'m-3 d-flex align-items-center justify-content-center'}>
|
||||
<ForkAwesomeIcon icon={'spinner'} className={'fa-spin'} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue