import type React from 'react'; import { useCallback, useMemo, useState } from 'react'; import type { IAttachmentHasId } from '@growi/core'; import { LoadingSpinner, UserPicture } from '@growi/ui/dist/components'; import { useTranslation } from 'next-i18next'; import { Button, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap'; import { toastError, toastSuccess } from '~/client/util/toastr'; import { useDeleteAttachmentModalActions, useDeleteAttachmentModalStatus, } from '~/states/ui/modal/delete-attachment'; import loggerFactory from '~/utils/logger'; import { Username } from '../../../components/User/Username'; import styles from './DeleteAttachmentModal.module.scss'; const logger = loggerFactory('growi:attachmentDelete'); const iconByFormat = (format: string): string => { return format.match(/image\/.+/i) ? 'image' : 'description'; }; /** * DeleteAttachmentModalSubstance - Presentation component (all logic here) */ type DeleteAttachmentModalSubstanceProps = { attachment: IAttachmentHasId | undefined; remove: ((args: { attachment_id: string }) => Promise) | undefined; closeModal: () => void; }; const DeleteAttachmentModalSubstance = ({ attachment, remove, closeModal, }: DeleteAttachmentModalSubstanceProps): React.JSX.Element => { const [deleting, setDeleting] = useState(false); const [deleteError, setDeleteError] = useState(''); const { t } = useTranslation(); const toggleHandler = useCallback(() => { closeModal(); setDeleting(false); setDeleteError(''); }, [closeModal]); const onClickDeleteButtonHandler = useCallback(async () => { if (remove == null || attachment == null) { return; } setDeleting(true); try { await remove({ attachment_id: attachment._id }); setDeleting(false); closeModal(); toastSuccess(`Delete ${attachment.originalName}`); } catch (err) { setDeleting(false); setDeleteError('Attachment could not be deleted.'); toastError(err); logger.error(err); } }, [attachment, closeModal, remove]); const attachmentFileFormat = useMemo(() => { if (attachment == null) { return; } const content = attachment.fileFormat.match(/image\/.+/i) ? ( deleting attachment ) : ( '' ); return (

{iconByFormat(attachment.fileFormat)} {' '} {attachment.originalName}

uploaded by{' '} {' '}

{content}
); }, [attachment]); const deletingIndicator = useMemo(() => { if (deleting) { return ; } if (deleteError) { return {deleteError}; } return <>; }, [deleting, deleteError]); return (
{t('delete_attachment_modal.confirm_delete_attachment')} {attachmentFileFormat}
{deletingIndicator}
); }; /** * DeleteAttachmentModal - Container component (lightweight, always rendered) */ export const DeleteAttachmentModal: React.FC = () => { const deleteAttachmentModal = useDeleteAttachmentModalStatus(); const { close: closeModal } = useDeleteAttachmentModalActions(); const isOpen = deleteAttachmentModal?.isOpened; return ( {isOpen && ( )} ); };