styles.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import {useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Location} from 'history';
  4. import EventTagsPill from 'sentry/components/events/eventTags/eventTagsPill';
  5. import {SecondaryHeader} from 'sentry/components/events/interfaces/spans/header';
  6. import Panel from 'sentry/components/panels/panel';
  7. import Pills from 'sentry/components/pills';
  8. import SearchBar from 'sentry/components/searchBar';
  9. import {t} from 'sentry/locale';
  10. import {space} from 'sentry/styles/space';
  11. import {Organization} from 'sentry/types';
  12. import {defined} from 'sentry/utils';
  13. import {TraceFullDetailed} from 'sentry/utils/performance/quickTrace/types';
  14. import {appendTagCondition} from 'sentry/utils/queryString';
  15. import {transactionSummaryRouteWithQuery} from 'sentry/views/performance/transactionSummary/utils';
  16. export {
  17. Row,
  18. SpanDetails as TransactionDetails,
  19. SpanDetailContainer as TransactionDetailsContainer,
  20. } from 'sentry/components/events/interfaces/spans/spanDetail';
  21. export const TraceSearchContainer = styled('div')`
  22. display: flex;
  23. width: 100%;
  24. `;
  25. export const TraceSearchBar = styled(SearchBar)`
  26. flex-grow: 1;
  27. `;
  28. export const TraceViewHeaderContainer = styled(SecondaryHeader)`
  29. border-top: none;
  30. border-bottom: 1px solid ${p => p.theme.border};
  31. position: sticky;
  32. top: 0;
  33. z-index: 1;
  34. `;
  35. export const TraceDetailHeader = styled('div')`
  36. display: grid;
  37. grid-template-columns: 1fr;
  38. gap: ${space(3)};
  39. margin-bottom: ${space(2)};
  40. @media (min-width: ${p => p.theme.breakpoints.medium}) {
  41. grid-template-columns: max-content max-content;
  42. grid-row-gap: 0;
  43. }
  44. `;
  45. export const TraceDetailBody = styled('div')`
  46. height: 100%;
  47. `;
  48. export const TraceViewContainer = styled('div')`
  49. overflow-x: hidden;
  50. border-bottom-left-radius: 3px;
  51. border-bottom-right-radius: 3px;
  52. `;
  53. export const TracePanel = styled(Panel)`
  54. height: 100%;
  55. overflow: auto;
  56. `;
  57. export const ProjectBadgeContainer = styled('span')`
  58. margin-right: ${space(0.75)};
  59. display: flex;
  60. flex-direction: column;
  61. justify-content: center;
  62. `;
  63. const StyledPills = styled(Pills)`
  64. padding-top: ${space(1.5)};
  65. `;
  66. export function Tags({
  67. location,
  68. organization,
  69. enableHiding,
  70. transaction,
  71. }: {
  72. location: Location;
  73. organization: Organization;
  74. transaction: TraceFullDetailed;
  75. enableHiding?: boolean;
  76. }) {
  77. const {tags} = transaction;
  78. const [showingAll, setShowingAll] = useState(enableHiding ? false : true);
  79. if (!tags || tags.length <= 0) {
  80. return null;
  81. }
  82. const orgSlug = organization.slug;
  83. const renderText = showingAll ? t('Show less') : t('Show more') + '...';
  84. return (
  85. <tr>
  86. <td className="key">Tags</td>
  87. <td className="value">
  88. <StyledPills>
  89. {tags.slice(0, showingAll ? tags.length : 5).map((tag, index) => {
  90. const {pathname: streamPath, query} = transactionSummaryRouteWithQuery({
  91. orgSlug,
  92. transaction: transaction.transaction,
  93. projectID: String(transaction.project_id),
  94. query: {
  95. ...location.query,
  96. query: appendTagCondition(location.query.query, tag.key, tag.value),
  97. },
  98. });
  99. return (
  100. <EventTagsPill
  101. key={!defined(tag.key) ? `tag-pill-${index}` : tag.key}
  102. tag={tag}
  103. projectSlug={transaction.project_slug}
  104. projectId={transaction.project_id.toString()}
  105. organization={organization}
  106. query={query}
  107. streamPath={streamPath}
  108. />
  109. );
  110. })}
  111. {tags.length > 5 && enableHiding && (
  112. <div style={{position: 'relative', height: '20px'}}>
  113. <a
  114. style={{position: 'absolute', bottom: '0px', whiteSpace: 'nowrap'}}
  115. onClick={() => setShowingAll(prev => !prev)}
  116. >
  117. {renderText}
  118. </a>
  119. </div>
  120. )}
  121. </StyledPills>
  122. </td>
  123. </tr>
  124. );
  125. }