InAppNotification.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import React from 'react';
  2. import { UserPicture } from '@growi/ui';
  3. import { InAppNotification as IInAppNotification } from '../../interfaces/in-app-notification';
  4. import { PageUpdateNotification, PageCommentNotification } from './NotificationContent';
  5. interface Props {
  6. notification: IInAppNotification
  7. onClick: any
  8. }
  9. export const InAppNotification = (props: Props): JSX.Element => {
  10. const { notification } = props;
  11. // TODO get actionUsers with mongoose virtual method by #79077
  12. const getActionUsers = () => {
  13. const latestActionUsers = notification.actionUsers.slice(0, 3);
  14. const latestUsers = latestActionUsers.map((user) => {
  15. return `@${user.name}`;
  16. });
  17. let actionedUsers = '';
  18. const latestUsersCount = latestUsers.length;
  19. if (latestUsersCount === 1) {
  20. actionedUsers = latestUsers[0];
  21. }
  22. else if (notification.actionUsers.length >= 4) {
  23. actionedUsers = `${latestUsers.slice(0, 2).join(', ')} and ${notification.actionUsers.length - 2} others`;
  24. }
  25. else {
  26. actionedUsers = latestUsers.join(', ');
  27. }
  28. return actionedUsers;
  29. };
  30. const renderUserPicture = (): JSX.Element => {
  31. const actionUsers = notification.actionUsers;
  32. if (actionUsers.length < 1) {
  33. return <></>;
  34. }
  35. if (actionUsers.length === 1) {
  36. return <UserPicture user={actionUsers[0]} size="md" noTooltip />;
  37. }
  38. return (
  39. <div className="position-relative">
  40. <UserPicture user={actionUsers[0]} size="md" noTooltip />
  41. <div className="position-absolute" style={{ top: 10, left: 10 }}>
  42. <UserPicture user={actionUsers[1]} size="md" noTooltip />
  43. </div>
  44. </div>
  45. );
  46. };
  47. const componentName = `${notification.targetModel}:${notification.action}`;
  48. const propsNew = {
  49. actionUsers: getActionUsers(),
  50. ...props,
  51. };
  52. const renderInAppNotificationContent = (): JSX.Element => {
  53. switch (componentName) {
  54. // TODO Is the naming of componentName too subtle?
  55. case 'Page:UPDATE':
  56. return <PageUpdateNotification {...propsNew} onClick={props.onClick(props.notification)} />;
  57. case 'Page:COMMENT_CREATE':
  58. case 'Page:COMMENT_UPDATE':
  59. return <PageCommentNotification {...propsNew} onClick={props.onClick(props.notification)} />;
  60. default:
  61. return <></>;
  62. }
  63. };
  64. return (
  65. <>
  66. <div className="dropdown-item d-flex flex-row mb-3">
  67. <div className="p-2 mr-2 d-flex align-items-center">
  68. {renderUserPicture()}
  69. </div>
  70. <div className="p-2">
  71. {renderInAppNotificationContent()}
  72. </div>
  73. </div>
  74. </>
  75. );
  76. };