inviteStatusMessage.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import styled from '@emotion/styled';
  2. import LoadingIndicator from 'sentry/components/loadingIndicator';
  3. import {IconCheckmark, IconWarning} from 'sentry/icons';
  4. import {t, tct, tn} from 'sentry/locale';
  5. import {space} from 'sentry/styles/space';
  6. import type {InviteStatus} from './types';
  7. interface Props {
  8. complete: boolean;
  9. hasDuplicateEmails: boolean;
  10. inviteStatus: InviteStatus;
  11. sendingInvites: boolean;
  12. willInvite: boolean;
  13. }
  14. export default function InviteStatusMessage({
  15. complete,
  16. hasDuplicateEmails,
  17. inviteStatus,
  18. sendingInvites,
  19. willInvite,
  20. }: Props) {
  21. if (sendingInvites) {
  22. return (
  23. <StatusMessage>
  24. <LoadingIndicator mini relative hideMessage size={16} />
  25. {willInvite
  26. ? t('Sending organization invitations\u2026')
  27. : t('Sending invite requests\u2026')}
  28. </StatusMessage>
  29. );
  30. }
  31. if (complete) {
  32. const statuses = Object.values(inviteStatus);
  33. const sentCount = statuses.filter(i => i.sent).length;
  34. const errorCount = statuses.filter(i => i.error).length;
  35. if (willInvite) {
  36. const invites = <strong>{tn('%s invite', '%s invites', sentCount)}</strong>;
  37. const tctComponents = {
  38. invites,
  39. failed: errorCount,
  40. };
  41. return (
  42. <StatusMessage status="success">
  43. <IconCheckmark size="sm" />
  44. <span>
  45. {errorCount > 0
  46. ? tct('Sent [invites], [failed] failed to send.', tctComponents)
  47. : tct('Sent [invites]', tctComponents)}
  48. </span>
  49. </StatusMessage>
  50. );
  51. }
  52. const inviteRequests = (
  53. <strong>{tn('%s invite request', '%s invite requests', sentCount)}</strong>
  54. );
  55. const tctComponents = {
  56. inviteRequests,
  57. failed: errorCount,
  58. };
  59. return (
  60. <StatusMessage status="success">
  61. <IconCheckmark size="sm" />
  62. {errorCount > 0
  63. ? tct(
  64. '[inviteRequests] pending approval, [failed] failed to send.',
  65. tctComponents
  66. )
  67. : tct('[inviteRequests] pending approval', tctComponents)}
  68. </StatusMessage>
  69. );
  70. }
  71. if (hasDuplicateEmails) {
  72. return (
  73. <StatusMessage status="error">
  74. <IconWarning size="sm" />
  75. {t('Duplicate emails between invite rows.')}
  76. </StatusMessage>
  77. );
  78. }
  79. return null;
  80. }
  81. export const StatusMessage = styled('div')<{status?: 'success' | 'error'}>`
  82. display: flex;
  83. gap: ${space(1)};
  84. align-items: center;
  85. font-size: ${p => p.theme.fontSizeMedium};
  86. color: ${p => (p.status === 'error' ? p.theme.errorText : p.theme.textColor)};
  87. > :first-child {
  88. ${p => p.status === 'success' && `color: ${p.theme.successText}`};
  89. }
  90. `;