renderHeadCell.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import {Location} from 'history';
  2. import {GridColumnHeader} from 'sentry/components/gridEditable';
  3. import SortLink, {Alignments} from 'sentry/components/gridEditable/sortLink';
  4. import {
  5. aggregateFunctionOutputType,
  6. fieldAlignment,
  7. parseFunction,
  8. Sort,
  9. } from 'sentry/utils/discover/fields';
  10. import {SpanFunction, SpanMetricsField} from 'sentry/views/starfish/types';
  11. import {QueryParameterNames} from 'sentry/views/starfish/views/queryParameters';
  12. type Options = {
  13. column: GridColumnHeader<string>;
  14. location?: Location;
  15. sort?: Sort;
  16. sortParameterName?:
  17. | QueryParameterNames.ENDPOINTS_SORT
  18. | QueryParameterNames.SPANS_SORT
  19. | typeof DEFAULT_SORT_PARAMETER_NAME;
  20. };
  21. const DEFAULT_SORT_PARAMETER_NAME = 'sort';
  22. const {SPAN_SELF_TIME} = SpanMetricsField;
  23. const {TIME_SPENT_PERCENTAGE, SPS, SPM, HTTP_ERROR_COUNT} = SpanFunction;
  24. export const SORTABLE_FIELDS = new Set([
  25. `avg(${SPAN_SELF_TIME})`,
  26. `p95(${SPAN_SELF_TIME})`,
  27. `p75(transaction.duration)`,
  28. `transaction.duration`,
  29. 'transaction',
  30. `count()`,
  31. `${SPS}()`,
  32. `${SPM}()`,
  33. `${TIME_SPENT_PERCENTAGE}()`,
  34. `${TIME_SPENT_PERCENTAGE}(local)`,
  35. `${HTTP_ERROR_COUNT}()`,
  36. ]);
  37. export const renderHeadCell = ({column, location, sort, sortParameterName}: Options) => {
  38. const {key, name} = column;
  39. const alignment = getAlignment(key);
  40. let newSortDirection: Sort['kind'] = 'desc';
  41. if (sort?.field === column.key) {
  42. if (sort.kind === 'desc') {
  43. newSortDirection = 'asc';
  44. }
  45. }
  46. const newSort = `${newSortDirection === 'desc' ? '-' : ''}${key}`;
  47. return (
  48. <SortLink
  49. align={alignment}
  50. canSort={Boolean(location && sort && SORTABLE_FIELDS.has(key))}
  51. direction={sort?.field === column.key ? sort.kind : undefined}
  52. title={name}
  53. generateSortLink={() => {
  54. return {
  55. ...location,
  56. query: {
  57. ...location?.query,
  58. [sortParameterName ?? DEFAULT_SORT_PARAMETER_NAME]: newSort,
  59. },
  60. };
  61. }}
  62. />
  63. );
  64. };
  65. export const getAlignment = (key: string): Alignments => {
  66. const result = parseFunction(key);
  67. if (result) {
  68. const outputType = aggregateFunctionOutputType(result.name, result.arguments[0]);
  69. if (outputType) {
  70. return fieldAlignment(key, outputType);
  71. }
  72. }
  73. return 'left';
  74. };