generic.tsx 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import {useState} from 'react';
  2. import {EventDataSection} from 'sentry/components/events/eventDataSection';
  3. import KeyValueList from 'sentry/components/events/interfaces/keyValueList';
  4. import {AnnotatedText} from 'sentry/components/events/meta/annotatedText';
  5. import {SegmentedControl} from 'sentry/components/segmentedControl';
  6. import {t} from 'sentry/locale';
  7. function getView({
  8. data,
  9. meta,
  10. view,
  11. }: {
  12. data: Props['data'];
  13. view: View;
  14. meta?: Record<any, any>;
  15. }) {
  16. switch (view) {
  17. case 'report':
  18. return !data ? (
  19. <AnnotatedText value={data} meta={meta?.['']} />
  20. ) : (
  21. <KeyValueList
  22. data={Object.entries(data).map(([key, value]) => ({
  23. key,
  24. value,
  25. subject: key,
  26. meta: meta?.[key]?.[''],
  27. }))}
  28. isContextData
  29. />
  30. );
  31. case 'raw':
  32. return <pre>{JSON.stringify({'csp-report': data}, null, 2)}</pre>;
  33. default:
  34. throw new TypeError(`Invalid view: ${view}`);
  35. }
  36. }
  37. type Props = {
  38. data: Record<string, any> | null;
  39. type: string;
  40. meta?: Record<string, any>;
  41. };
  42. type View = 'report' | 'raw';
  43. export function Generic({type, data, meta}: Props) {
  44. const [view, setView] = useState<View>('report');
  45. return (
  46. <EventDataSection
  47. type={type}
  48. title={t('Report')}
  49. actions={
  50. <SegmentedControl
  51. aria-label={t('View')}
  52. size="xs"
  53. value={view}
  54. onChange={setView}
  55. >
  56. <SegmentedControl.Item key="report">{t('Report')}</SegmentedControl.Item>
  57. <SegmentedControl.Item key="raw">{t('Raw')}</SegmentedControl.Item>
  58. </SegmentedControl>
  59. }
  60. >
  61. {getView({view, data, meta})}
  62. </EventDataSection>
  63. );
  64. }