InAppNotificationElm.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import React, { FC } from 'react';
  2. import type { HasObjectId } from '@growi/core';
  3. import { UserPicture } from '@growi/ui/dist/components';
  4. import { DropdownItem } from 'reactstrap';
  5. import { apiv3Post } from '~/client/util/apiv3-client';
  6. import { IInAppNotification, InAppNotificationStatuses } from '~/interfaces/in-app-notification';
  7. import { useModelNotification } from './PageNotification';
  8. interface Props {
  9. notification: IInAppNotification & HasObjectId
  10. elemClassName?: string,
  11. type?: 'button' | 'dropdown-item',
  12. }
  13. const InAppNotificationElm: FC<Props> = (props: Props) => {
  14. const { notification } = props;
  15. const modelNotificationUtils = useModelNotification(notification);
  16. const Notification = modelNotificationUtils?.Notification;
  17. const publishOpen = modelNotificationUtils?.publishOpen;
  18. if (Notification == null || publishOpen == null) {
  19. return <></>;
  20. }
  21. const clickHandler = async(notification: IInAppNotification & HasObjectId): Promise<void> => {
  22. if (notification.status === InAppNotificationStatuses.STATUS_UNOPENED) {
  23. // set notification status "OPEND"
  24. await apiv3Post('/in-app-notification/open', { id: notification._id });
  25. }
  26. publishOpen();
  27. };
  28. const renderActionUserPictures = (): JSX.Element => {
  29. const actionUsers = notification.actionUsers;
  30. if (actionUsers.length < 1) {
  31. return <></>;
  32. }
  33. if (actionUsers.length === 1) {
  34. return <UserPicture user={actionUsers[0]} size="md" noTooltip />;
  35. }
  36. return (
  37. <div className="position-relative">
  38. <UserPicture user={actionUsers[0]} size="md" noTooltip />
  39. <div className="position-absolute" style={{ top: 10, left: 10 }}>
  40. <UserPicture user={actionUsers[1]} size="md" noTooltip />
  41. </div>
  42. </div>
  43. );
  44. };
  45. const isDropdownItem = props.type === 'dropdown-item';
  46. // determine tag
  47. const TagElem = isDropdownItem
  48. ? DropdownItem
  49. // eslint-disable-next-line react/prop-types
  50. : props => <button type="button" {...props}>{props.children}</button>;
  51. return (
  52. <TagElem className={props.elemClassName} onClick={() => clickHandler(notification)}>
  53. <div className="d-flex align-items-center">
  54. <span
  55. className={`${notification.status === InAppNotificationStatuses.STATUS_UNOPENED
  56. ? 'grw-unopend-notification'
  57. : 'ms-2'
  58. } rounded-circle me-3`}
  59. >
  60. </span>
  61. {renderActionUserPictures()}
  62. <Notification />
  63. </div>
  64. </TagElem>
  65. );
  66. };
  67. export default InAppNotificationElm;