generic.tsx 1.7 KB

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