contextSummaryUser.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import styled from '@emotion/styled';
  2. import UserAvatar from 'sentry/components/avatar/userAvatar';
  3. import {removeFilterMaskedEntries} from 'sentry/components/events/interfaces/utils';
  4. import AnnotatedText from 'sentry/components/events/meta/annotatedText';
  5. import TextOverflow from 'sentry/components/textOverflow';
  6. import {t} from 'sentry/locale';
  7. import space from 'sentry/styles/space';
  8. import {AvatarUser, Event, Meta} from 'sentry/types';
  9. import {EventUser} from 'sentry/types/event';
  10. import {defined} from 'sentry/utils';
  11. import ContextSummaryNoSummary from './contextSummaryNoSummary';
  12. import Item from './item';
  13. type Props = {
  14. data: EventUser;
  15. meta: NonNullable<Event['_meta']>['user'];
  16. };
  17. type UserTitle = {
  18. value: string;
  19. meta?: Meta;
  20. };
  21. type UserDetails = {
  22. subject: string;
  23. meta?: Meta;
  24. value?: string;
  25. };
  26. export function ContextSummaryUser({data, meta}: Props) {
  27. const user = removeFilterMaskedEntries(data);
  28. if (Object.keys(user).length === 0) {
  29. return <ContextSummaryNoSummary title={t('Unknown User')} />;
  30. }
  31. const renderUserDetails = (key: 'id' | 'username') => {
  32. const userDetails: UserDetails = {
  33. subject: t('Username:'),
  34. value: user.username ?? '',
  35. meta: meta.username?.[''],
  36. };
  37. if (key === 'id') {
  38. userDetails.subject = t('ID:');
  39. userDetails.value = user.id;
  40. userDetails.meta = meta.id?.[''];
  41. }
  42. return (
  43. <TextOverflow isParagraph data-test-id="context-sub-title">
  44. <Subject>{userDetails.subject}</Subject>
  45. <AnnotatedText value={userDetails.value} meta={userDetails.meta} />
  46. </TextOverflow>
  47. );
  48. };
  49. const getUserTitle = (): UserTitle | undefined => {
  50. if (defined(user.email)) {
  51. return {
  52. value: user.email,
  53. meta: meta.email?.[''],
  54. };
  55. }
  56. if (defined(user.ip_address)) {
  57. return {
  58. value: user.ip_address,
  59. meta: meta.ip_address?.[''],
  60. };
  61. }
  62. if (defined(user.id)) {
  63. return {
  64. value: user.id,
  65. meta: meta.id?.[''],
  66. };
  67. }
  68. if (defined(user.username)) {
  69. return {
  70. value: user.username,
  71. meta: meta.username?.[''],
  72. };
  73. }
  74. return undefined;
  75. };
  76. const userTitle = getUserTitle();
  77. if (!userTitle) {
  78. return <ContextSummaryNoSummary title={t('Unknown User')} />;
  79. }
  80. const icon = userTitle ? (
  81. <UserAvatar
  82. user={user as AvatarUser}
  83. size={32}
  84. className="context-item-icon"
  85. gravatar={false}
  86. />
  87. ) : (
  88. <span className="context-item-icon" />
  89. );
  90. return (
  91. <Item className="user" icon={icon}>
  92. {userTitle && (
  93. <h3 data-test-id="user-title">
  94. <AnnotatedText value={userTitle.value} meta={userTitle.meta} />
  95. </h3>
  96. )}
  97. {defined(user.id) && user.id !== userTitle?.value
  98. ? renderUserDetails('id')
  99. : user.username &&
  100. user.username !== userTitle?.value &&
  101. renderUserDetails('username')}
  102. </Item>
  103. );
  104. }
  105. const Subject = styled('strong')`
  106. margin-right: ${space(0.5)};
  107. `;