UserMenu.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import React, { useState, useCallback } from 'react';
  2. import { IUserHasId, USER_STATUS } from '@growi/core';
  3. import { useTranslation } from 'next-i18next';
  4. import {
  5. UncontrolledDropdown, DropdownToggle, DropdownMenu,
  6. } from 'reactstrap';
  7. import AdminUsersContainer from '~/client/services/AdminUsersContainer';
  8. import { withUnstatedContainers } from '../../UnstatedUtils';
  9. import GiveAdminButton from './GiveAdminButton';
  10. import RemoveAdminMenuItem from './RemoveAdminMenuItem';
  11. import SendInvitationEmailButton from './SendInvitationEmailButton';
  12. import StatusActivateButton from './StatusActivateButton';
  13. import StatusSuspendedMenuItem from './StatusSuspendMenuItem';
  14. import UserRemoveButton from './UserRemoveButton';
  15. import styles from './UserMenu.module.scss';
  16. type UserMenuProps = {
  17. adminUsersContainer: AdminUsersContainer,
  18. user: IUserHasId,
  19. }
  20. const UserMenu = (props: UserMenuProps) => {
  21. const { t } = useTranslation('admin');
  22. const { adminUsersContainer, user } = props;
  23. const [isInvitationEmailSended, setIsInvitationEmailSended] = useState<boolean>(user.isInvitationEmailSended);
  24. const onClickPasswordResetHandler = useCallback(async() => {
  25. await adminUsersContainer.showPasswordResetModal(user);
  26. }, [adminUsersContainer, user]);
  27. const onSuccessfullySentInvitationEmailHandler = useCallback(() => {
  28. setIsInvitationEmailSended(true);
  29. }, []);
  30. const renderEditMenu = useCallback(() => {
  31. return (
  32. <>
  33. <li className="dropdown-divider"></li>
  34. <li className="dropdown-header">{t('user_management.user_table.edit_menu')}</li>
  35. <li>
  36. <button className="dropdown-item" type="button" onClick={onClickPasswordResetHandler}>
  37. <i className="icon-fw icon-key"></i>{ t('user_management.reset_password') }
  38. </button>
  39. </li>
  40. </>
  41. );
  42. }, [onClickPasswordResetHandler, t]);
  43. const renderStatusMenu = useCallback(() => {
  44. return (
  45. <>
  46. <li className="dropdown-divider"></li>
  47. <li className="dropdown-header">{t('user_management.status')}</li>
  48. <li>
  49. {(user.status === USER_STATUS.REGISTERED || user.status === USER_STATUS.SUSPENDED) && <StatusActivateButton user={user} />}
  50. {user.status === USER_STATUS.ACTIVE && <StatusSuspendedMenuItem user={user} />}
  51. {user.status === USER_STATUS.INVITED && (
  52. <SendInvitationEmailButton
  53. user={user}
  54. isInvitationEmailSended={isInvitationEmailSended}
  55. onSuccessfullySentInvitationEmail={onSuccessfullySentInvitationEmailHandler}
  56. />
  57. )}
  58. {(user.status === USER_STATUS.REGISTERED || user.status === USER_STATUS.SUSPENDED || user.status === USER_STATUS.INVITED)
  59. && <UserRemoveButton user={user} />}
  60. </li>
  61. </>
  62. );
  63. }, [isInvitationEmailSended, onSuccessfullySentInvitationEmailHandler, t, user]);
  64. const renderAdminMenu = useCallback(() => {
  65. return (
  66. <>
  67. <li className="dropdown-divider pl-0"></li>
  68. <li className="dropdown-header">{t('user_management.user_table.administrator_menu')}</li>
  69. <li>
  70. {user.admin === true && <RemoveAdminMenuItem user={user} />}
  71. {user.admin === false && <GiveAdminButton user={user} />}
  72. </li>
  73. </>
  74. );
  75. }, [t, user]);
  76. return (
  77. <UncontrolledDropdown id="userMenu" size="sm">
  78. <DropdownToggle caret color="secondary" outline>
  79. <i className="icon-settings" />
  80. {(user.status === USER_STATUS.INVITED && !isInvitationEmailSended)
  81. && <i className={`fa fa-circle text-danger grw-usermenu-notification-icon ${styles['grw-usermenu-notification-icon']}`} />}
  82. </DropdownToggle>
  83. <DropdownMenu positionFixed>
  84. {renderEditMenu()}
  85. {user.status !== USER_STATUS.DELETED && renderStatusMenu()}
  86. {user.status === USER_STATUS.ACTIVE && renderAdminMenu()}
  87. </DropdownMenu>
  88. </UncontrolledDropdown>
  89. );
  90. };
  91. /**
  92. * Wrapper component for using unstated
  93. */
  94. // eslint-disable-next-line max-len
  95. const UserMenuWrapper: React.ForwardRefExoticComponent<Pick<any, string | number | symbol> & React.RefAttributes<any>> = withUnstatedContainers(UserMenu, [AdminUsersContainer]);
  96. export default UserMenuWrapper;