mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-04-16 21:27:27 +00:00
refactor: Deduplicate delete modal (#1734)
This commit is contained in:
parent
6a6f6105b9
commit
5f228b1bf2
4 changed files with 62 additions and 36 deletions
|
@ -11,36 +11,58 @@ import { DeletionModal } from '../../../common/modals/deletion-modal'
|
|||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||
import type { ModalVisibilityProps } from '../../../common/modals/common-modal'
|
||||
|
||||
export interface DeleteHistoryNoteModalProps {
|
||||
modalTitleI18nKey?: string
|
||||
modalQuestionI18nKey?: string
|
||||
modalWarningI18nKey?: string
|
||||
modalButtonI18nKey?: string
|
||||
}
|
||||
|
||||
export interface DeleteNoteModalProps extends ModalVisibilityProps {
|
||||
optionalNoteTitle?: string
|
||||
onConfirm: () => void
|
||||
}
|
||||
|
||||
/**
|
||||
* A modal that asks the user if they really want to delete the current note.
|
||||
*
|
||||
* @param optionalNoteTitle optional note title
|
||||
* @param show Defines if the modal should be shown
|
||||
* @param onHide A callback that fires if the modal should be hidden without confirmation
|
||||
* @param onConfirm A callback that fires if the user confirmed the request
|
||||
* @param modalTitleI18nKey optional i18nKey for the title
|
||||
* @param modalQuestionI18nKey optional i18nKey for the question
|
||||
* @param modalWarningI18nKey optional i18nKey for the warning
|
||||
* @param modalButtonI18nKey optional i18nKey for the button
|
||||
*/
|
||||
export const DeleteNoteModal: React.FC<DeleteNoteModalProps> = ({ show, onHide, onConfirm }) => {
|
||||
export const DeleteNoteModal: React.FC<DeleteNoteModalProps & DeleteHistoryNoteModalProps> = ({
|
||||
optionalNoteTitle,
|
||||
show,
|
||||
onHide,
|
||||
onConfirm,
|
||||
modalTitleI18nKey,
|
||||
modalQuestionI18nKey,
|
||||
modalWarningI18nKey,
|
||||
modalButtonI18nKey
|
||||
}) => {
|
||||
const noteTitle = useApplicationState((state) => state.noteDetails.noteTitle)
|
||||
|
||||
return (
|
||||
<DeletionModal
|
||||
{...cypressId('sidebar.deleteNote.modal')}
|
||||
onConfirm={onConfirm}
|
||||
deletionButtonI18nKey={'editor.modal.deleteNote.button'}
|
||||
deletionButtonI18nKey={modalButtonI18nKey ?? 'editor.modal.deleteNote.button'}
|
||||
show={show}
|
||||
onHide={onHide}
|
||||
title={'editor.modal.deleteNote.title'}>
|
||||
title={modalTitleI18nKey ?? 'editor.modal.deleteNote.title'}>
|
||||
<h5>
|
||||
<Trans i18nKey={'editor.modal.deleteNote.question'} />
|
||||
<Trans i18nKey={modalQuestionI18nKey ?? 'editor.modal.deleteNote.question'} />
|
||||
</h5>
|
||||
<ul>
|
||||
<li {...cypressId('sidebar.deleteNote.modal.noteTitle')}> {noteTitle}</li>
|
||||
<li {...cypressId('sidebar.deleteNote.modal.noteTitle')}>{optionalNoteTitle ?? noteTitle}</li>
|
||||
</ul>
|
||||
<h6>
|
||||
<Trans i18nKey={'editor.modal.deleteNote.warning'} />
|
||||
<Trans i18nKey={modalWarningI18nKey ?? 'editor.modal.deleteNote.warning'} />
|
||||
</h6>
|
||||
</DeletionModal>
|
||||
)
|
||||
|
|
|
@ -17,11 +17,7 @@ export const DeleteNoteItem: React.FC<DeleteNoteItemProps> = ({ noteTitle, onCon
|
|||
<DropdownItemWithDeletionModal
|
||||
onConfirm={onConfirm}
|
||||
itemI18nKey={'landing.history.menu.deleteNote'}
|
||||
modalButtonI18nKey={'editor.modal.deleteNote.button'}
|
||||
modalIcon={'trash'}
|
||||
modalTitleI18nKey={'editor.modal.deleteNote.title'}
|
||||
modalQuestionI18nKey={'editor.modal.deleteNote.question'}
|
||||
modalWarningI18nKey={'editor.modal.deleteNote.warning'}
|
||||
noteTitle={noteTitle}
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -4,26 +4,38 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import React, { Fragment, useState } from 'react'
|
||||
import React, { Fragment, useCallback, useState } from 'react'
|
||||
import { Dropdown } from 'react-bootstrap'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
|
||||
import type { IconName } from '../../common/fork-awesome/types'
|
||||
import { DeletionModal } from '../../common/modals/deletion-modal'
|
||||
import type { DeleteHistoryNoteModalProps } from '../../editor-page/sidebar/delete-note-sidebar-entry/delete-note-modal'
|
||||
import { DeleteNoteModal } from '../../editor-page/sidebar/delete-note-sidebar-entry/delete-note-modal'
|
||||
|
||||
export interface DropdownItemWithDeletionModalProps {
|
||||
onConfirm: () => void
|
||||
itemI18nKey: string
|
||||
modalButtonI18nKey: string
|
||||
modalIcon: IconName
|
||||
modalTitleI18nKey: string
|
||||
modalQuestionI18nKey: string
|
||||
modalWarningI18nKey: string
|
||||
noteTitle: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const DropdownItemWithDeletionModal: React.FC<DropdownItemWithDeletionModalProps> = ({
|
||||
/**
|
||||
* Renders a dropdown item and the corresponding deletion modal
|
||||
*
|
||||
* @param onConfirm A callback that fires if the user confirmed the request
|
||||
* @param noteTitle The note title to be displayed
|
||||
* @param modalTitleI18nKey The i18nKey for title to be shown in the modal
|
||||
* @param modalButtonI18nKey The i18nKey for button to be shown in the modal
|
||||
* @param itemI18nKey The i18nKey for the dropdown item
|
||||
* @param modalIcon The icon for the dropdown item
|
||||
* @param modalQuestionI18nKey The i18nKey for question to be shown in the modal
|
||||
* @param modalWarningI18nKey The i18nKey for warning to be shown in the modal
|
||||
* @param className Additional classes given to the dropdown item
|
||||
*/
|
||||
export const DropdownItemWithDeletionModal: React.FC<
|
||||
DropdownItemWithDeletionModalProps & DeleteHistoryNoteModalProps
|
||||
> = ({
|
||||
onConfirm,
|
||||
noteTitle,
|
||||
modalTitleI18nKey,
|
||||
|
@ -36,6 +48,11 @@ export const DropdownItemWithDeletionModal: React.FC<DropdownItemWithDeletionMod
|
|||
}) => {
|
||||
useTranslation()
|
||||
const [showDialog, setShowDialog] = useState(false)
|
||||
const handleConfirm = useCallback(() => {
|
||||
setShowDialog(false)
|
||||
onConfirm()
|
||||
}, [onConfirm])
|
||||
const onHide = useCallback(() => setShowDialog(false), [])
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
@ -43,25 +60,16 @@ export const DropdownItemWithDeletionModal: React.FC<DropdownItemWithDeletionMod
|
|||
<ForkAwesomeIcon icon={modalIcon} fixedWidth={true} className='mx-2' />
|
||||
<Trans i18nKey={itemI18nKey} />
|
||||
</Dropdown.Item>
|
||||
<DeletionModal
|
||||
onConfirm={() => {
|
||||
setShowDialog(false)
|
||||
onConfirm()
|
||||
}}
|
||||
deletionButtonI18nKey={modalButtonI18nKey}
|
||||
<DeleteNoteModal
|
||||
optionalNoteTitle={noteTitle}
|
||||
onConfirm={handleConfirm}
|
||||
show={showDialog}
|
||||
onHide={() => setShowDialog(false)}
|
||||
title={modalTitleI18nKey}>
|
||||
<h5>
|
||||
<Trans i18nKey={modalQuestionI18nKey} />
|
||||
</h5>
|
||||
<ul>
|
||||
<li>{noteTitle}</li>
|
||||
</ul>
|
||||
<h6>
|
||||
<Trans i18nKey={modalWarningI18nKey} />
|
||||
</h6>
|
||||
</DeletionModal>
|
||||
onHide={onHide}
|
||||
modalTitleI18nKey={modalTitleI18nKey}
|
||||
modalButtonI18nKey={modalButtonI18nKey}
|
||||
modalQuestionI18nKey={modalQuestionI18nKey}
|
||||
modalWarningI18nKey={modalWarningI18nKey}
|
||||
/>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ export const HistoryCard: React.FC<HistoryEntryProps & HistoryEventHandlers> = (
|
|||
<div className={'d-flex flex-column'}>
|
||||
<EntryMenu
|
||||
id={entry.identifier}
|
||||
title={entry.title}
|
||||
title={entryTitle}
|
||||
origin={entry.origin}
|
||||
isDark={false}
|
||||
onRemove={onRemove}
|
||||
|
|
Loading…
Add table
Reference in a new issue