evidencePreview.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import {ReactChild, useEffect} from 'react';
  2. import styled from '@emotion/styled';
  3. import KeyValueList from 'sentry/components/events/interfaces/keyValueList';
  4. import {GroupPreviewHovercard} from 'sentry/components/groupPreviewTooltip/groupPreviewHovercard';
  5. import {
  6. useDelayedLoadingState,
  7. usePreviewEvent,
  8. } from 'sentry/components/groupPreviewTooltip/utils';
  9. import LoadingIndicator from 'sentry/components/loadingIndicator';
  10. import {t} from 'sentry/locale';
  11. import {space} from 'sentry/styles/space';
  12. type SpanEvidencePreviewProps = {
  13. children: ReactChild;
  14. groupId: string;
  15. query?: string;
  16. };
  17. type SpanEvidencePreviewBodyProps = {
  18. groupId: string;
  19. onRequestBegin: () => void;
  20. onRequestEnd: () => void;
  21. onUnmount: () => void;
  22. query?: string;
  23. };
  24. function SpanEvidencePreviewBody({
  25. onRequestBegin,
  26. onRequestEnd,
  27. onUnmount,
  28. groupId,
  29. query,
  30. }: SpanEvidencePreviewBodyProps) {
  31. const {data, isLoading, isError} = usePreviewEvent({groupId, query});
  32. useEffect(() => {
  33. if (isLoading) {
  34. onRequestBegin();
  35. } else {
  36. onRequestEnd();
  37. }
  38. return onUnmount;
  39. }, [isLoading, onRequestBegin, onRequestEnd, onUnmount]);
  40. if (isLoading) {
  41. return (
  42. <EmptyWrapper>
  43. <LoadingIndicator hideMessage size={32} />
  44. </EmptyWrapper>
  45. );
  46. }
  47. if (isError) {
  48. return <EmptyWrapper>{t('Failed to load preview')}</EmptyWrapper>;
  49. }
  50. const evidenceDisplay = data?.occurrence?.evidenceDisplay;
  51. if (evidenceDisplay?.length) {
  52. return (
  53. <SpanEvidencePreviewWrapper data-test-id="evidence-preview-body">
  54. <KeyValueList
  55. data={evidenceDisplay.map(item => ({
  56. key: item.name,
  57. subject: item.name,
  58. value: item.value,
  59. }))}
  60. shouldSort={false}
  61. />
  62. </SpanEvidencePreviewWrapper>
  63. );
  64. }
  65. return (
  66. <EmptyWrapper>{t('There is no evidence available for this issue.')}</EmptyWrapper>
  67. );
  68. }
  69. export function EvidencePreview({children, groupId, query}: SpanEvidencePreviewProps) {
  70. const {shouldShowLoadingState, onRequestBegin, onRequestEnd, reset} =
  71. useDelayedLoadingState();
  72. return (
  73. <GroupPreviewHovercard
  74. hide={!shouldShowLoadingState}
  75. body={
  76. <SpanEvidencePreviewBody
  77. onRequestBegin={onRequestBegin}
  78. onRequestEnd={onRequestEnd}
  79. onUnmount={reset}
  80. groupId={groupId}
  81. query={query}
  82. />
  83. }
  84. >
  85. {children}
  86. </GroupPreviewHovercard>
  87. );
  88. }
  89. const EmptyWrapper = styled('div')`
  90. color: ${p => p.theme.subText};
  91. padding: ${space(1.5)};
  92. font-size: ${p => p.theme.fontSizeMedium};
  93. display: flex;
  94. align-items: center;
  95. justify-content: center;
  96. min-height: 56px;
  97. `;
  98. const SpanEvidencePreviewWrapper = styled('div')`
  99. width: 700px;
  100. padding: ${space(1.5)} ${space(1.5)} 0 ${space(1.5)};
  101. `;