Attachment.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import type { JSX } from 'react';
  2. import type { IAttachmentHasId } from '@growi/core';
  3. import { format } from 'date-fns/format';
  4. import { UserPicture } from './UserPicture';
  5. type AttachmentProps = {
  6. attachment: IAttachmentHasId;
  7. inUse: boolean;
  8. onAttachmentDeleteClicked?: (attachment: IAttachmentHasId) => void;
  9. isUserLoggedIn?: boolean;
  10. };
  11. export const Attachment = (props: AttachmentProps): JSX.Element => {
  12. const { attachment, inUse, isUserLoggedIn, onAttachmentDeleteClicked } =
  13. props;
  14. const _onAttachmentDeleteClicked = () => {
  15. if (onAttachmentDeleteClicked != null) {
  16. onAttachmentDeleteClicked(attachment);
  17. }
  18. };
  19. const formatIcon = attachment.fileFormat.match(/image\/.+/i)
  20. ? 'image'
  21. : 'description';
  22. const btnDownload = isUserLoggedIn ? (
  23. <a className="attachment-download" href={attachment.downloadPathProxied}>
  24. <span className="material-symbols-outlined">cloud_download</span>
  25. </a>
  26. ) : (
  27. ''
  28. );
  29. const btnTrash = isUserLoggedIn ? (
  30. <button
  31. className="text-danger attachment-delete btn btn-link p-0"
  32. onClick={_onAttachmentDeleteClicked}
  33. type="button"
  34. >
  35. <span className="material-symbols-outlined">delete</span>
  36. </button>
  37. ) : (
  38. ''
  39. );
  40. const fileType = (
  41. <span className="attachment-filetype badge bg-secondary rounded-pill">
  42. {attachment.fileFormat}
  43. </span>
  44. );
  45. const fileInUse = inUse ? (
  46. <span className="attachment-in-use badge bg-info rounded-pill">In Use</span>
  47. ) : (
  48. ''
  49. );
  50. // Should UserDate be used like PageRevisionTable ?
  51. const formatType = 'yyyy/MM/dd HH:mm:ss';
  52. const createdAt = format(new Date(attachment.createdAt), formatType);
  53. return (
  54. <div className="attachment mb-2">
  55. <span className="me-1 attachment-userpicture">
  56. <UserPicture user={attachment.creator} size="sm" />
  57. </span>
  58. <a
  59. className="me-2"
  60. href={attachment.filePathProxied}
  61. target="_blank"
  62. rel="noopener noreferrer"
  63. >
  64. <span className="material-symbols-outlined ms-1">{formatIcon}</span>{' '}
  65. {attachment.originalName}
  66. </a>
  67. <span className="me-2">{fileType}</span>
  68. <span className="me-2">{createdAt}</span>
  69. <span className="me-2">{fileInUse}</span>
  70. <span className="me-2">{btnDownload}</span>
  71. <span className="me-2">{btnTrash}</span>
  72. </div>
  73. );
  74. };