allEventsTable.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import {useState} from 'react';
  2. import {Location} from 'history';
  3. import LoadingError from 'sentry/components/loadingError';
  4. import {PlatformCategory, PlatformKey} from 'sentry/data/platformCategories';
  5. import {t} from 'sentry/locale';
  6. import {Group, IssueCategory, Organization} from 'sentry/types';
  7. import EventView, {decodeSorts} from 'sentry/utils/discover/eventView';
  8. import {platformToCategory} from 'sentry/utils/platform';
  9. import {useRoutes} from 'sentry/utils/useRoutes';
  10. import EventsTable from 'sentry/views/performance/transactionSummary/transactionEvents/eventsTable';
  11. export interface Props {
  12. group: Group;
  13. issueId: string;
  14. location: Location;
  15. organization: Organization;
  16. excludedTags?: string[];
  17. }
  18. const AllEventsTable = (props: Props) => {
  19. const {location, organization, issueId, excludedTags, group} = props;
  20. const [error, setError] = useState<string>('');
  21. const routes = useRoutes();
  22. const {fields, columnTitles} = getColumns(group, organization);
  23. const eventView: EventView = EventView.fromLocation(props.location);
  24. eventView.fields = fields.map(fieldName => ({field: fieldName}));
  25. eventView.sorts = decodeSorts(location).filter(sort => fields.includes(sort.field));
  26. if (!eventView.sorts.length) {
  27. eventView.sorts = [{field: 'timestamp', kind: 'desc'}];
  28. }
  29. const idQuery =
  30. group.issueCategory === IssueCategory.PERFORMANCE
  31. ? `performance.issue_ids:${issueId} event.type:transaction`
  32. : `issue.id:${issueId}`;
  33. eventView.project = [parseInt(group.project.id, 10)];
  34. eventView.query = `${idQuery} ${props.location.query.query || ''}`;
  35. eventView.statsPeriod = '90d';
  36. if (error) {
  37. return <LoadingError message={error} />;
  38. }
  39. const isReplayEnabled = organization.features.includes('session-replay-ui');
  40. return (
  41. <EventsTable
  42. eventView={eventView}
  43. location={location}
  44. issueId={issueId}
  45. organization={organization}
  46. routes={routes}
  47. excludedTags={excludedTags}
  48. projectSlug={group.project.slug}
  49. totalEventCount={group.count}
  50. customColumns={['minidump']}
  51. setError={(msg: string | undefined) => setError(msg ?? '')}
  52. transactionName=""
  53. columnTitles={columnTitles.slice()}
  54. referrer="api.issues.issue_events"
  55. showReplayCol={isReplayEnabled}
  56. />
  57. );
  58. };
  59. type ColumnInfo = {columnTitles: string[]; fields: string[]};
  60. const getColumns = (group: Group, organization: Organization): ColumnInfo => {
  61. const isPerfIssue = group.issueCategory === IssueCategory.PERFORMANCE;
  62. const isReplayEnabled = organization.features.includes('session-replay-ui');
  63. const {fields: platformSpecificFields, columnTitles: platformSpecificColumnTitles} =
  64. getPlatformColumns(group.project.platform ?? group.platform, {isReplayEnabled});
  65. const fields: string[] = [
  66. 'id',
  67. 'transaction',
  68. 'title',
  69. 'release',
  70. 'environment',
  71. 'user.display',
  72. 'device',
  73. 'os',
  74. ...platformSpecificFields,
  75. ...(isPerfIssue ? ['transaction.duration'] : []),
  76. 'timestamp',
  77. ];
  78. const columnTitles: string[] = [
  79. t('event id'),
  80. t('transaction'),
  81. t('title'),
  82. t('release'),
  83. t('environment'),
  84. t('user'),
  85. t('device'),
  86. t('os'),
  87. ...platformSpecificColumnTitles,
  88. ...(isPerfIssue ? [t('total duration')] : []),
  89. t('timestamp'),
  90. t('minidump'),
  91. ];
  92. return {
  93. fields,
  94. columnTitles,
  95. };
  96. };
  97. const getPlatformColumns = (
  98. platform: PlatformKey | undefined,
  99. options: {isReplayEnabled: boolean}
  100. ): ColumnInfo => {
  101. const replayField = options.isReplayEnabled ? ['replayId'] : [];
  102. const replayColumnTitle = options.isReplayEnabled ? [t('replay')] : [];
  103. const backendServerlessColumnInfo = {
  104. fields: ['url', 'runtime'],
  105. columnTitles: [t('url'), t('runtime')],
  106. };
  107. const categoryToColumnMap: Record<PlatformCategory, ColumnInfo> = {
  108. [PlatformCategory.BACKEND]: backendServerlessColumnInfo,
  109. [PlatformCategory.SERVERLESS]: backendServerlessColumnInfo,
  110. [PlatformCategory.FRONTEND]: {
  111. fields: ['url', 'browser', ...replayField],
  112. columnTitles: [t('url'), t('browser'), ...replayColumnTitle],
  113. },
  114. [PlatformCategory.MOBILE]: {
  115. fields: ['url'],
  116. columnTitles: [t('url')],
  117. },
  118. [PlatformCategory.DESKTOP]: {
  119. fields: [],
  120. columnTitles: [],
  121. },
  122. [PlatformCategory.OTHER]: {
  123. fields: [],
  124. columnTitles: [],
  125. },
  126. };
  127. const platformCategory = platformToCategory(platform);
  128. return categoryToColumnMap[platformCategory];
  129. };
  130. export default AllEventsTable;