renderHeadCell.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import type {Location} from 'history';
  2. import type {GridColumnHeader} from 'sentry/components/gridEditable';
  3. import type {Alignments} from 'sentry/components/gridEditable/sortLink';
  4. import SortLink from 'sentry/components/gridEditable/sortLink';
  5. import type {Sort} from 'sentry/utils/discover/fields';
  6. import {
  7. aggregateFunctionOutputType,
  8. fieldAlignment,
  9. parseFunction,
  10. } from 'sentry/utils/discover/fields';
  11. import type {QueryParameterNames} from 'sentry/views/insights/common/views/queryParameters';
  12. import {
  13. SpanFunction,
  14. SpanIndexedField,
  15. SpanMetricsField,
  16. } from 'sentry/views/insights/types';
  17. type Options = {
  18. column: GridColumnHeader<string>;
  19. location?: Location;
  20. sort?: Sort;
  21. sortParameterName?: QueryParameterNames | typeof DEFAULT_SORT_PARAMETER_NAME;
  22. };
  23. const DEFAULT_SORT_PARAMETER_NAME = 'sort';
  24. const {SPAN_SELF_TIME, SPAN_DURATION, HTTP_RESPONSE_CONTENT_LENGTH, CACHE_ITEM_SIZE} =
  25. SpanMetricsField;
  26. const {
  27. TIME_SPENT_PERCENTAGE,
  28. SPS,
  29. SPM,
  30. HTTP_ERROR_COUNT,
  31. HTTP_RESPONSE_RATE,
  32. CACHE_HIT_RATE,
  33. CACHE_MISS_RATE,
  34. } = SpanFunction;
  35. export const SORTABLE_FIELDS = new Set([
  36. `avg(${SPAN_SELF_TIME})`,
  37. `avg(${SPAN_DURATION})`,
  38. `sum(${SPAN_SELF_TIME})`,
  39. `p95(${SPAN_SELF_TIME})`,
  40. `p75(transaction.duration)`,
  41. `transaction.duration`,
  42. 'transaction',
  43. `count()`,
  44. `${SPS}()`,
  45. `${SPM}()`,
  46. `${TIME_SPENT_PERCENTAGE}()`,
  47. `${HTTP_ERROR_COUNT}()`,
  48. `${HTTP_RESPONSE_RATE}(2)`,
  49. `${HTTP_RESPONSE_RATE}(4)`,
  50. `${HTTP_RESPONSE_RATE}(5)`,
  51. `avg(${HTTP_RESPONSE_CONTENT_LENGTH})`,
  52. `${CACHE_HIT_RATE}()`,
  53. `${CACHE_MISS_RATE}()`,
  54. SpanIndexedField.TIMESTAMP,
  55. SpanIndexedField.SPAN_DURATION,
  56. `avg(${CACHE_ITEM_SIZE})`,
  57. SpanIndexedField.MESSAGING_MESSAGE_DESTINATION_NAME,
  58. 'count_op(queue.publish)',
  59. 'count_op(queue.process)',
  60. 'avg_if(span.duration,span.op,queue.process)',
  61. 'avg(messaging.message.receive.latency)',
  62. 'time_spent_percentage(app,span.duration)',
  63. ]);
  64. const NUMERIC_FIELDS = new Set([
  65. 'transaction.duration',
  66. SpanMetricsField.CACHE_ITEM_SIZE,
  67. SpanIndexedField.SPAN_SELF_TIME,
  68. SpanIndexedField.SPAN_DURATION,
  69. SpanIndexedField.CACHE_ITEM_SIZE,
  70. SpanIndexedField.MESSAGING_MESSAGE_BODY_SIZE,
  71. SpanIndexedField.MESSAGING_MESSAGE_RETRY_COUNT,
  72. ]);
  73. export const renderHeadCell = ({column, location, sort, sortParameterName}: Options) => {
  74. const {key, name} = column;
  75. const alignment = getAlignment(key);
  76. let newSortDirection: Sort['kind'] = 'desc';
  77. if (sort?.field === column.key) {
  78. if (sort.kind === 'desc') {
  79. newSortDirection = 'asc';
  80. }
  81. }
  82. const newSort = `${newSortDirection === 'desc' ? '-' : ''}${key}`;
  83. return (
  84. <SortLink
  85. align={alignment}
  86. canSort={Boolean(location && sort && SORTABLE_FIELDS.has(key))}
  87. direction={sort?.field === column.key ? sort.kind : undefined}
  88. title={name}
  89. generateSortLink={() => {
  90. return {
  91. ...location,
  92. query: {
  93. ...location?.query,
  94. [sortParameterName ?? DEFAULT_SORT_PARAMETER_NAME]: newSort,
  95. },
  96. };
  97. }}
  98. />
  99. );
  100. };
  101. export const getAlignment = (key: string): Alignments => {
  102. const result = parseFunction(key);
  103. if (result) {
  104. const outputType = aggregateFunctionOutputType(result.name, result.arguments[0]);
  105. if (outputType) {
  106. return fieldAlignment(key, outputType);
  107. }
  108. } else {
  109. if (NUMERIC_FIELDS.has(key)) {
  110. return 'right';
  111. }
  112. }
  113. return 'left';
  114. };