DeleteAttachmentModal.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* eslint-disable react/prop-types */
  2. import React, { useCallback } from 'react';
  3. import { HasObjectId, IAttachment } from '@growi/core';
  4. import { UserPicture } from '@growi/ui';
  5. import {
  6. Button,
  7. Modal, ModalHeader, ModalBody, ModalFooter,
  8. } from 'reactstrap';
  9. import Username from '../User/Username';
  10. function iconNameByFormat(format: string): string {
  11. if (format.match(/image\/.+/i)) {
  12. return 'icon-picture';
  13. }
  14. return 'icon-doc';
  15. }
  16. type Props = {
  17. isOpen: boolean,
  18. toggle: () => void,
  19. attachmentToDelete: IAttachment & HasObjectId | null,
  20. deleting: boolean,
  21. deleteError: string,
  22. onAttachmentDeleteClickedConfirm?: (attachment: IAttachment & HasObjectId) => Promise<void>,
  23. }
  24. export const DeleteAttachmentModal = (props: Props): JSX.Element => {
  25. const {
  26. isOpen, toggle,
  27. attachmentToDelete, deleting, deleteError,
  28. onAttachmentDeleteClickedConfirm,
  29. } = props;
  30. const onDeleteConfirm = useCallback(() => {
  31. if (attachmentToDelete == null || onAttachmentDeleteClickedConfirm == null) {
  32. return;
  33. }
  34. onAttachmentDeleteClickedConfirm(attachmentToDelete);
  35. }, [attachmentToDelete, onAttachmentDeleteClickedConfirm]);
  36. const renderByFileFormat = useCallback((attachment) => {
  37. const content = (attachment.fileFormat.match(/image\/.+/i))
  38. // eslint-disable-next-line @next/next/no-img-element
  39. ? <img src={attachment.filePathProxied} alt="deleting image" />
  40. : '';
  41. return (
  42. <div className="attachment-delete-image">
  43. <p>
  44. <i className={iconNameByFormat(attachment.fileFormat)}></i> {attachment.originalName}
  45. </p>
  46. <p>
  47. uploaded by <UserPicture user={attachment.creator} size="sm"></UserPicture> <Username user={attachment.creator}></Username>
  48. </p>
  49. {content}
  50. </div>
  51. );
  52. }, []);
  53. let deletingIndicator = <></>;
  54. if (deleting) {
  55. deletingIndicator = <div className="speeding-wheel-sm"></div>;
  56. }
  57. if (deleteError) {
  58. deletingIndicator = <span>{deleteError}</span>;
  59. }
  60. return (
  61. <Modal isOpen={isOpen} className="attachment-delete-modal" size="lg" aria-labelledby="contained-modal-title-lg" fade={false}>
  62. <ModalHeader tag="h4" toggle={toggle} className="bg-danger text-light">
  63. <span id="contained-modal-title-lg">Delete attachment?</span>
  64. </ModalHeader>
  65. <ModalBody>
  66. {renderByFileFormat(attachmentToDelete)}
  67. </ModalBody>
  68. <ModalFooter>
  69. <div className="mr-3 d-inline-block">
  70. {deletingIndicator}
  71. </div>
  72. <Button
  73. color="danger"
  74. onClick={onDeleteConfirm}
  75. disabled={deleting}
  76. >Delete!
  77. </Button>
  78. </ModalFooter>
  79. </Modal>
  80. );
  81. };