InAppNotificationElm.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import React, { useState, useEffect } from 'react';
  2. import { UserPicture, PagePathLabel } from '@growi/ui';
  3. import { IUser } from 'src/interfaces/user';
  4. import { IInAppNotification } from '../../interfaces/in-app-notification';
  5. // import { PageUpdateNotification, PageCommentNotification } from './NotificationContent';
  6. import { apiv3Post } from '../../client/util/apiv3-client';
  7. import FormattedDistanceDate from '../FormattedDistanceDate';
  8. import loggerFactory from '~/utils/logger';
  9. const logger = loggerFactory('growi:InAppNotificationElm');
  10. interface Props {
  11. notification: IInAppNotification
  12. }
  13. const InAppNotificationElm = (props: Props): JSX.Element => {
  14. const { notification } = props;
  15. const getActionUsers = () => {
  16. const latestActionUsers = notification.actionUsers.slice(0, 3);
  17. const latestUsers = latestActionUsers.map((user) => {
  18. return `@${user.name}`;
  19. });
  20. let actionedUsers = '';
  21. const latestUsersCount = latestUsers.length;
  22. if (latestUsersCount === 1) {
  23. actionedUsers = latestUsers[0];
  24. }
  25. else if (notification.actionUsers.length >= 4) {
  26. actionedUsers = `${latestUsers.slice(0, 2).join(', ')} and ${notification.actionUsers.length - 2} others`;
  27. }
  28. else {
  29. actionedUsers = latestUsers.join(', ');
  30. }
  31. return actionedUsers;
  32. };
  33. const renderUserPicture = (): JSX.Element => {
  34. const actionUsers = notification.actionUsers;
  35. if (actionUsers.length < 1) {
  36. return <></>;
  37. }
  38. if (actionUsers.length === 1) {
  39. return <UserPicture user={actionUsers[0]} size="md" noTooltip />;
  40. }
  41. return (
  42. <div className="position-relative">
  43. <UserPicture user={actionUsers[0]} size="md" noTooltip />
  44. <div className="position-absolute" style={{ top: 10, left: 10 }}>
  45. <UserPicture user={actionUsers[1]} size="md" noTooltip />
  46. </div>
  47. </div>
  48. );
  49. };
  50. const notificationClickHandler = async() => {
  51. try {
  52. // set notification status "STATUS_OPEND"
  53. await apiv3Post('/in-app-notification/open', { id: notification._id });
  54. // jump to target page
  55. window.location.href = notification.target.path;
  56. }
  57. catch (err) {
  58. logger.error(err);
  59. }
  60. };
  61. const actionUsers = getActionUsers();
  62. const pagePath = { path: props.notification.target.path };
  63. const actionType: string = notification.action;
  64. let actionMsg: string;
  65. switch (actionType) {
  66. case 'PAGE_UPDATE':
  67. actionMsg = 'updated on';
  68. break;
  69. case 'COMMENT_CREATE':
  70. actionMsg = 'commented on';
  71. break;
  72. default:
  73. actionMsg = '';
  74. }
  75. return (
  76. <>
  77. <div className="dropdown-item d-flex flex-row mb-3">
  78. <div className="p-2 mr-2 d-flex align-items-center">
  79. {renderUserPicture()}
  80. </div>
  81. <div className="p-2">
  82. <div onClick={() => notificationClickHandler()}>
  83. <div>
  84. <b>{actionUsers}</b> {actionMsg} <PagePathLabel page={pagePath} />
  85. </div>
  86. <i className="fa fa-file-o mr-2" />
  87. <FormattedDistanceDate id={notification._id} date={notification.createdAt} isShowTooltip={false} />
  88. </div>
  89. </div>
  90. </div>
  91. </>
  92. );
  93. };
  94. export default InAppNotificationElm;