Refactoring of modals (#294)

* Refactored modals (added CommonModal and DeletionModal besides ErrorModal)

This change allows more code reusage by defining a common modal that has a translated title with an optional icon.

* Replace the eslint-hack with a proper TypeScript conform solution

Instead of asserting non-null and disabling eslint, the 'as ...'-syntax is used to convince the compiler that everything is fine.

* Improved property names and ShowIf-construct

* Fixed missing renamings
This commit is contained in:
Erik Michelson 2020-06-28 00:00:05 +02:00 committed by GitHub
parent 17102d7d44
commit d13adcc9c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 89 additions and 56 deletions

View file

@ -1,32 +0,0 @@
import React, { Fragment } from 'react'
import { Modal } from 'react-bootstrap'
import { Trans } from 'react-i18next'
import { ForkAwesomeIcon, IconName } from '../fork-awesome/fork-awesome-icon'
export interface ErrorModalProps {
show: boolean
onHide: () => void
title: string
icon?: IconName
}
export const ErrorModal: React.FC<ErrorModalProps> = ({ show, onHide, title, icon, children }) => {
return (
<Modal show={show} onHide={onHide} animation={true} className="text-dark">
<Modal.Header closeButton>
<Modal.Title>
{icon
? <Fragment>
<ForkAwesomeIcon icon={icon}/>&nbsp;<Trans i18nKey={title}/>
</Fragment>
: <Trans i18nKey={title}/>
}
</Modal.Title>
</Modal.Header>
<Modal.Body className="text-dark text-center">
{children}
</Modal.Body>
</Modal>
)
}

View file

@ -0,0 +1,31 @@
import React from 'react'
import { Modal } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
import { ForkAwesomeIcon, IconName } from '../fork-awesome/fork-awesome-icon'
import { ShowIf } from '../show-if/show-if'
export interface CommonModalProps {
show: boolean
onHide: () => void
titleI18nKey: string
closeButton?: boolean
icon?: IconName
}
export const CommonModal: React.FC<CommonModalProps> = ({ show, onHide, titleI18nKey, closeButton, icon, children }) => {
useTranslation()
return (
<Modal show={show} onHide={onHide} animation={true} className="text-dark">
<Modal.Header closeButton={!!closeButton}>
<Modal.Title>
<ShowIf condition={!!icon}>
<ForkAwesomeIcon icon={icon as IconName}/>&nbsp;
</ShowIf>
<Trans i18nKey={titleI18nKey}/>
</Modal.Title>
</Modal.Header>
{ children }
</Modal>
)
}

View file

@ -0,0 +1,26 @@
import React from 'react'
import { Modal, Button } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
import { CommonModal, CommonModalProps } from './common-modal'
export interface DeletionModalProps extends CommonModalProps {
onConfirm: () => void
deletionButtonI18nKey: string
}
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>
<Modal.Footer>
<Button variant="danger" onClick={onConfirm}>
<Trans i18nKey={deletionButtonI18nKey}/>
</Button>
</Modal.Footer>
</CommonModal>
)
}

View file

@ -0,0 +1,13 @@
import React from 'react'
import { Modal } from 'react-bootstrap'
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>
)
}

View file

@ -1,7 +1,8 @@
import React, { Fragment, useState } from 'react'
import { Button, Modal } from 'react-bootstrap'
import { Button } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-icon'
import { DeletionModal } from '../../../../common/modals/deletion-modal'
export interface ClearHistoryButtonProps {
onClearHistory: () => void
@ -19,25 +20,19 @@ export const ClearHistoryButton: React.FC<ClearHistoryButtonProps> = ({ onClearH
<Button variant={'light'} title={t('landing.history.toolbar.clear')} onClick={handleShow}>
<ForkAwesomeIcon icon={'trash'}/>
</Button>
<Modal show={show} onHide={handleClose} animation={true} className="text-dark">
<Modal.Header closeButton>
<Modal.Title>
<Trans i18nKey={'landing.history.modal.clearHistory.title'}/>
</Modal.Title>
</Modal.Header>
<Modal.Body className="text-dark">
<h5><Trans i18nKey={'landing.history.modal.clearHistory.question'}/></h5>
<h6><Trans i18nKey={'landing.history.modal.clearHistory.disclaimer'}/></h6>
</Modal.Body>
<Modal.Footer>
<Button variant="danger" onClick={() => {
onClearHistory()
handleClose()
}}>
<Trans i18nKey={'landing.history.toolbar.clear'}/>
</Button>
</Modal.Footer>
</Modal>
<DeletionModal
onConfirm={() => {
onClearHistory()
handleClose()
}}
deletionButtonI18nKey={'landing.history.toolbar.clear'}
show={show}
onHide={handleClose}
titleI18nKey={'landing.history.modal.clearHistory.title'}
>
<h5><Trans i18nKey={'landing.history.modal.clearHistory.question'}/></h5>
<h6><Trans i18nKey={'landing.history.modal.clearHistory.disclaimer'}/></h6>
</DeletionModal>
</Fragment>
)
}

View file

@ -2,7 +2,7 @@ import React, { useRef, useState } from 'react'
import { Button } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
import { convertV1History, V1HistoryEntry } from '../../../../../utils/historyUtils'
import { ErrorModal } from '../../../../common/error-modal/error-modal'
import { ErrorModal } from '../../../../common/modals/error-modal'
import { ForkAwesomeIcon } from '../../../../common/fork-awesome/fork-awesome-icon'
import { HistoryEntry, HistoryJson } from '../history'
@ -78,7 +78,7 @@ export const ImportHistoryButton: React.FC<ImportHistoryButtonProps> = ({ onImpo
<ErrorModal
show={show}
onHide={handleClose}
title='landing.history.modal.importHistoryError.title'
titleI18nKey='landing.history.modal.importHistoryError.title'
icon='exclamation-circle'
>
{fileName !== ''

View file

@ -13,7 +13,7 @@ import {
setHistoryToLocalStore,
sortAndFilterEntries
} from '../../../../utils/historyUtils'
import { ErrorModal } from '../../../common/error-modal/error-modal'
import { ErrorModal } from '../../../common/modals/error-modal'
import { HistoryContent } from './history-content/history-content'
import { HistoryToolbar, HistoryToolbarState, initState as toolbarInitState } from './history-toolbar/history-toolbar'
@ -195,7 +195,7 @@ export const History: React.FC = () => {
return (
<Fragment>
<ErrorModal show={error !== ''} onHide={resetError}
title={error !== '' ? `landing.history.error.${error}.title` : ''}>
titleI18nKey={error !== '' ? `landing.history.error.${error}.title` : ''}>
<h5>
<Trans i18nKey={error !== '' ? `landing.history.error.${error}.text` : ''}/>
</h5>