chunk.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import {Fragment, useCallback, useEffect, useState} from 'react';
  2. import {EventDataSection} from 'sentry/components/events/eventDataSection';
  3. import plugins from 'sentry/plugins';
  4. import type {Event} from 'sentry/types/event';
  5. import type {Group} from 'sentry/types/group';
  6. import {defined} from 'sentry/utils';
  7. import {
  8. getContextComponent,
  9. getContextMeta,
  10. getContextTitle,
  11. getSourcePlugin,
  12. } from './utils';
  13. type Props = {
  14. alias: string;
  15. event: Event;
  16. type: string;
  17. group?: Group;
  18. value?: Record<string, any>;
  19. };
  20. /**
  21. * @deprecated Legacy design, use ContextCard instead
  22. */
  23. export function Chunk({group, type, alias, value = {}, event}: Props) {
  24. const [pluginLoading, setPluginLoading] = useState(false);
  25. const syncPlugin = useCallback(() => {
  26. // If we don't have a grouped event we can't sync with plugins.
  27. if (!group) {
  28. return;
  29. }
  30. // Search using `alias` first because old plugins rely on it and type is set to "default"
  31. // e.g. sessionstack
  32. const sourcePlugin =
  33. type === 'default'
  34. ? getSourcePlugin(group.pluginContexts, alias) ||
  35. getSourcePlugin(group.pluginContexts, type)
  36. : getSourcePlugin(group.pluginContexts, type);
  37. if (!sourcePlugin) {
  38. setPluginLoading(false);
  39. return;
  40. }
  41. setPluginLoading(true);
  42. plugins.load(sourcePlugin, () => {
  43. setPluginLoading(false);
  44. });
  45. }, [alias, type, group]);
  46. useEffect(() => {
  47. syncPlugin();
  48. }, [type, group?.id, syncPlugin]);
  49. // if we are currently loading the plugin, just render nothing for now.
  50. if (pluginLoading) {
  51. return null;
  52. }
  53. // we intentionally hide reprocessing context to not imply it was sent by the SDK.
  54. if (alias === 'reprocessing') {
  55. return null;
  56. }
  57. const ContextComponent =
  58. type === 'default'
  59. ? getContextComponent(alias) || getContextComponent(type)
  60. : getContextComponent(type);
  61. const isObjectValueEmpty = Object.values(value).filter(v => defined(v)).length === 0;
  62. // this can happen if the component does not exist
  63. if (!ContextComponent || isObjectValueEmpty) {
  64. return null;
  65. }
  66. return (
  67. <EventDataSection
  68. key={`context-${alias}`}
  69. type={`context-${alias}`}
  70. title={
  71. <Fragment>
  72. {getContextTitle({value, alias, type})}
  73. {defined(type) && type !== 'default' && alias !== type && (
  74. <small>({alias})</small>
  75. )}
  76. </Fragment>
  77. }
  78. >
  79. <ContextComponent
  80. alias={alias}
  81. event={event}
  82. data={value}
  83. meta={getContextMeta(event, type)}
  84. />
  85. </EventDataSection>
  86. );
  87. }