resourceTable.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import {Fragment} from 'react';
  2. import {Link} from 'react-router';
  3. import GridEditable, {
  4. COL_WIDTH_UNDEFINED,
  5. GridColumnHeader,
  6. GridColumnOrder,
  7. } from 'sentry/components/gridEditable';
  8. import Pagination from 'sentry/components/pagination';
  9. import {t} from 'sentry/locale';
  10. import {useLocation} from 'sentry/utils/useLocation';
  11. import {ValidSort} from 'sentry/views/performance/browser/resources/imageView/utils/useImageResourceSort';
  12. import {useIndexedResourcesQuery} from 'sentry/views/performance/browser/resources/imageView/utils/useIndexedResourcesQuery';
  13. import ResourceSize from 'sentry/views/performance/browser/resources/shared/resourceSize';
  14. import {DurationCell} from 'sentry/views/starfish/components/tableCells/durationCell';
  15. import {renderHeadCell} from 'sentry/views/starfish/components/tableCells/renderHeadCell';
  16. import {WiderHovercard} from 'sentry/views/starfish/components/tableCells/spanDescriptionCell';
  17. import {SpanMetricsField} from 'sentry/views/starfish/types';
  18. const {SPAN_DESCRIPTION, SPAN_SELF_TIME, HTTP_RESPONSE_CONTENT_LENGTH} = SpanMetricsField;
  19. type Row = {
  20. 'http.response_content_length': number;
  21. id: string;
  22. project: string;
  23. 'resource.render_blocking_status': '' | 'non-blocking' | 'blocking';
  24. 'span.description': string;
  25. 'span.self_time': number;
  26. };
  27. type Column = GridColumnHeader<keyof Row>;
  28. type Props = {
  29. sort: ValidSort;
  30. };
  31. function ResourceTable({sort}: Props) {
  32. const location = useLocation();
  33. const {data, isLoading, pageLinks} = useIndexedResourcesQuery();
  34. const columnOrder: GridColumnOrder<keyof Row>[] = [
  35. {key: SPAN_DESCRIPTION, width: COL_WIDTH_UNDEFINED, name: 'Resource name'},
  36. {key: `${SPAN_SELF_TIME}`, width: COL_WIDTH_UNDEFINED, name: 'Duration'},
  37. {
  38. key: HTTP_RESPONSE_CONTENT_LENGTH,
  39. width: COL_WIDTH_UNDEFINED,
  40. name: t('Resource size'),
  41. },
  42. ];
  43. const tableData: Row[] = data.length
  44. ? data.map(span => ({
  45. ...span,
  46. 'http.decoded_response_content_length': Math.floor(
  47. Math.random() * (1000 - 500) + 500
  48. ),
  49. }))
  50. : [];
  51. const renderBodyCell = (col: Column, row: Row) => {
  52. const {key} = col;
  53. if (key === SPAN_DESCRIPTION) {
  54. return (
  55. <WiderHovercard
  56. position="right"
  57. body={
  58. <div style={{width: '100px'}}>
  59. <img src={row[key]} />
  60. </div>
  61. }
  62. >
  63. <Link
  64. to={`/performance/${row.project}:${row['transaction.id']}#span-${row.id}`}
  65. >
  66. {row[key]}
  67. </Link>
  68. </WiderHovercard>
  69. );
  70. }
  71. if (key === 'http.response_content_length') {
  72. return <ResourceSize bytes={row[key]} />;
  73. }
  74. if (key === `span.self_time`) {
  75. return <DurationCell milliseconds={row[key]} />;
  76. }
  77. return <span>{row[key]}</span>;
  78. };
  79. return (
  80. <Fragment>
  81. <GridEditable
  82. data={tableData}
  83. isLoading={isLoading}
  84. columnOrder={columnOrder}
  85. columnSortBy={[
  86. {
  87. key: sort.field,
  88. order: sort.kind,
  89. },
  90. ]}
  91. grid={{
  92. renderHeadCell: column =>
  93. renderHeadCell({
  94. column,
  95. location,
  96. sort,
  97. }),
  98. renderBodyCell,
  99. }}
  100. location={location}
  101. />
  102. <Pagination pageLinks={pageLinks} />
  103. </Fragment>
  104. );
  105. }
  106. export default ResourceTable;