crashActions.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import styled from '@emotion/styled';
  2. import Button from 'sentry/components/button';
  3. import ButtonBar from 'sentry/components/buttonBar';
  4. import {t} from 'sentry/locale';
  5. import space from 'sentry/styles/space';
  6. import {
  7. ExceptionType,
  8. ExceptionValue,
  9. STACK_TYPE,
  10. STACK_VIEW,
  11. Thread,
  12. } from 'sentry/types';
  13. type NotifyOptions = {
  14. stackType?: STACK_TYPE;
  15. stackView?: STACK_VIEW;
  16. };
  17. type Props = {
  18. hasHierarchicalGrouping: boolean;
  19. exception?: ExceptionType;
  20. onChange?: (notifyOptions: NotifyOptions) => void;
  21. platform?: string;
  22. stackType?: STACK_TYPE;
  23. stackView?: STACK_VIEW;
  24. stacktrace?: ExceptionValue['stacktrace'];
  25. thread?: Thread;
  26. };
  27. const CrashActions = ({
  28. hasHierarchicalGrouping,
  29. stackView,
  30. stackType,
  31. stacktrace,
  32. thread,
  33. exception,
  34. platform,
  35. onChange,
  36. }: Props) => {
  37. const hasSystemFrames: boolean =
  38. stacktrace?.hasSystemFrames ||
  39. !!exception?.values?.find(value => !!value.stacktrace?.hasSystemFrames);
  40. const hasMinified = !stackType
  41. ? false
  42. : !!exception?.values?.find(value => value.rawStacktrace) || !!thread?.rawStacktrace;
  43. const notify = (options: NotifyOptions) => {
  44. if (onChange) {
  45. onChange(options);
  46. }
  47. };
  48. const setStackType = (type: STACK_TYPE) => () => {
  49. notify({stackType: type});
  50. };
  51. const setStackView = (view: STACK_VIEW) => () => {
  52. notify({stackView: view});
  53. };
  54. const getOriginalButtonLabel = () => {
  55. if (platform === 'javascript' || platform === 'node') {
  56. return t('Original');
  57. }
  58. return t('Symbolicated');
  59. };
  60. const getMinifiedButtonLabel = () => {
  61. if (platform === 'javascript' || platform === 'node') {
  62. return t('Minified');
  63. }
  64. return t('Unsymbolicated');
  65. };
  66. return (
  67. <ButtonGroupWrapper>
  68. <ButtonBar active={stackView} merged>
  69. {hasSystemFrames && (
  70. <Button
  71. barId={STACK_VIEW.APP}
  72. size="xs"
  73. onClick={setStackView(STACK_VIEW.APP)}
  74. title={
  75. hasHierarchicalGrouping
  76. ? t(
  77. 'The stack trace only shows application frames and frames responsible for grouping this issue'
  78. )
  79. : undefined
  80. }
  81. >
  82. {hasHierarchicalGrouping ? t('Most Relevant') : t('App Only')}
  83. </Button>
  84. )}
  85. <Button barId={STACK_VIEW.FULL} size="xs" onClick={setStackView(STACK_VIEW.FULL)}>
  86. {t('Full')}
  87. </Button>
  88. <Button barId={STACK_VIEW.RAW} onClick={setStackView(STACK_VIEW.RAW)} size="xs">
  89. {t('Raw')}
  90. </Button>
  91. </ButtonBar>
  92. {hasMinified && (
  93. <ButtonBar active={stackType} merged>
  94. <Button
  95. barId={STACK_TYPE.ORIGINAL}
  96. size="xs"
  97. onClick={setStackType(STACK_TYPE.ORIGINAL)}
  98. >
  99. {getOriginalButtonLabel()}
  100. </Button>
  101. <Button
  102. barId={STACK_TYPE.MINIFIED}
  103. size="xs"
  104. onClick={setStackType(STACK_TYPE.MINIFIED)}
  105. >
  106. {getMinifiedButtonLabel()}
  107. </Button>
  108. </ButtonBar>
  109. )}
  110. </ButtonGroupWrapper>
  111. );
  112. };
  113. export default CrashActions;
  114. const ButtonGroupWrapper = styled('div')`
  115. display: flex;
  116. flex-wrap: wrap;
  117. > * {
  118. padding: ${space(0.5)} 0;
  119. }
  120. > *:not(:last-child) {
  121. margin-right: ${space(1)};
  122. }
  123. `;