similarScoreCard.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import {t} from 'sentry/locale';
  4. import space from 'sentry/styles/space';
  5. const scoreComponents = {
  6. 'exception:message:character-shingles': t('Exception Message'),
  7. 'exception:stacktrace:pairs': t('Stack Trace Frames'),
  8. 'exception:stacktrace:application-chunks': t('In-App Frames'),
  9. 'message:message:character-shingles': t('Log Message'),
  10. // v2
  11. 'similarity:*:type:character-5-shingle': t('Exception Type'),
  12. 'similarity:*:value:character-5-shingle': t('Exception Message'),
  13. 'similarity:*:stacktrace:frames-pairs': t('Stack Trace Frames'),
  14. 'similarity:*:message:character-5-shingle': t('Log Message'),
  15. };
  16. type ScoreValue = number | null;
  17. type Props = {
  18. // we treat the score list keys as opaque as we wish to be able to extend the
  19. // backend without having to fix UI. Keys not in scoreComponents are grouped
  20. // into Other anyway
  21. scoreList?: [string, ScoreValue][];
  22. };
  23. const SimilarScoreCard = ({scoreList = []}: Props) => {
  24. if (scoreList.length === 0) {
  25. return null;
  26. }
  27. let sumOtherScores = 0;
  28. let numOtherScores = 0;
  29. return (
  30. <Fragment>
  31. {scoreList.map(([key, score]) => {
  32. const title =
  33. scoreComponents[key.replace(/similarity:\d\d\d\d-\d\d-\d\d/, 'similarity:*')];
  34. if (!title) {
  35. if (score !== null) {
  36. sumOtherScores += score;
  37. numOtherScores += 1;
  38. }
  39. return null;
  40. }
  41. return (
  42. <Wrapper key={key}>
  43. <div>{title}</div>
  44. <Score score={score === null ? score : Math.round(score * 4)} />
  45. </Wrapper>
  46. );
  47. })}
  48. {numOtherScores > 0 && sumOtherScores > 0 && (
  49. <Wrapper>
  50. <div>{t('Other')}</div>
  51. <Score score={Math.round((sumOtherScores * 4) / numOtherScores)} />
  52. </Wrapper>
  53. )}
  54. </Fragment>
  55. );
  56. };
  57. const Wrapper = styled('div')`
  58. display: flex;
  59. justify-content: space-between;
  60. margin: ${space(0.25)} 0;
  61. `;
  62. const Score = styled('div')<{score: ScoreValue}>`
  63. height: 16px;
  64. width: 48px;
  65. border-radius: 2px;
  66. background-color: ${p =>
  67. p.score === null ? p.theme.similarity.empty : p.theme.similarity.colors[p.score]};
  68. `;
  69. export default SimilarScoreCard;