screensTable.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import {Fragment} from 'react';
  2. import type {
  3. GridColumn,
  4. GridColumnHeader,
  5. GridColumnSortBy,
  6. } from 'sentry/components/gridEditable';
  7. import GridEditable, {COL_WIDTH_UNDEFINED} from 'sentry/components/gridEditable';
  8. import SortLink from 'sentry/components/gridEditable/sortLink';
  9. import Pagination from 'sentry/components/pagination';
  10. import {defined} from 'sentry/utils';
  11. import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
  12. import type EventView from 'sentry/utils/discover/eventView';
  13. import {isFieldSortable} from 'sentry/utils/discover/eventView';
  14. import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
  15. import {fieldAlignment} from 'sentry/utils/discover/fields';
  16. import {useLocation} from 'sentry/utils/useLocation';
  17. import useOrganization from 'sentry/utils/useOrganization';
  18. import {PercentChangeCell} from 'sentry/views/starfish/components/tableCells/percentChangeCell';
  19. type Props = {
  20. columnNameMap: Record<string, string>;
  21. columnOrder: string[];
  22. data: TableData | undefined;
  23. defaultSort: GridColumnSortBy<string>[];
  24. eventView: EventView;
  25. isLoading: boolean;
  26. pageLinks: string | undefined;
  27. customBodyCellRenderer?: (
  28. column: GridColumn<string>,
  29. row: TableDataRow
  30. ) => React.ReactNode;
  31. };
  32. export function ScreensTable({
  33. data,
  34. eventView,
  35. isLoading,
  36. pageLinks,
  37. columnNameMap,
  38. columnOrder,
  39. defaultSort,
  40. customBodyCellRenderer,
  41. }: Props) {
  42. const location = useLocation();
  43. const organization = useOrganization();
  44. function renderBodyCell(
  45. column: GridColumn<string>,
  46. row: TableDataRow
  47. ): React.ReactNode {
  48. if (!data?.meta || !data?.meta.fields) {
  49. return row[column.key];
  50. }
  51. if (defined(customBodyCellRenderer)) {
  52. const customRenderedCell = customBodyCellRenderer(column, row);
  53. if (defined(customRenderedCell)) {
  54. return customRenderedCell;
  55. }
  56. }
  57. if (data.meta.fields[column.key] === 'percent_change') {
  58. return (
  59. <PercentChangeCell
  60. deltaValue={parseFloat(row[column.key] as string) || 0}
  61. preferredPolarity="-"
  62. />
  63. );
  64. }
  65. const renderer = getFieldRenderer(column.key, data?.meta.fields, false);
  66. return renderer(row, {
  67. location,
  68. organization,
  69. unit: data?.meta.units?.[column.key],
  70. });
  71. }
  72. function renderHeadCell(column: GridColumnHeader): React.ReactNode {
  73. const fieldType = data?.meta?.fields?.[column.key];
  74. const alignment = fieldAlignment(column.key as string, fieldType);
  75. const field = {
  76. field: column.key as string,
  77. width: column.width,
  78. };
  79. function generateSortLink() {
  80. if (!data?.meta) {
  81. return undefined;
  82. }
  83. const nextEventView = eventView.sortOnField(field, data?.meta);
  84. const queryStringObject = nextEventView.generateQueryStringObject();
  85. return {
  86. ...location,
  87. query: {...location.query, sort: queryStringObject.sort},
  88. };
  89. }
  90. const currentSort = eventView.sortForField(field, data?.meta);
  91. const currentSortKind = currentSort ? currentSort.kind : undefined;
  92. const canSort = isFieldSortable(field, data?.meta);
  93. const sortLink = (
  94. <SortLink
  95. align={alignment}
  96. title={column.name}
  97. direction={currentSortKind}
  98. canSort={canSort}
  99. generateSortLink={generateSortLink}
  100. />
  101. );
  102. return sortLink;
  103. }
  104. return (
  105. <Fragment>
  106. <GridEditable
  107. isLoading={isLoading}
  108. data={data?.data as TableDataRow[]}
  109. columnOrder={columnOrder.map(columnKey => {
  110. return {
  111. key: columnKey,
  112. name: columnNameMap[columnKey],
  113. width: COL_WIDTH_UNDEFINED,
  114. };
  115. })}
  116. columnSortBy={defaultSort}
  117. location={location}
  118. grid={{
  119. renderHeadCell,
  120. renderBodyCell,
  121. }}
  122. />
  123. <Pagination pageLinks={pageLinks} />
  124. </Fragment>
  125. );
  126. }