simpleTableChart.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import {Component, Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Location} from 'history';
  4. import PanelTable, {PanelTableHeader} from 'sentry/components/panels/panelTable';
  5. import space from 'sentry/styles/space';
  6. import {Organization} from 'sentry/types';
  7. import {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
  8. import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
  9. import {fieldAlignment} from 'sentry/utils/discover/fields';
  10. import withOrganization from 'sentry/utils/withOrganization';
  11. import {decodeColumnOrder} from 'sentry/views/eventsV2/utils';
  12. type Props = {
  13. organization: Organization;
  14. location: Location;
  15. loading: boolean;
  16. fields: string[];
  17. title: string;
  18. metadata: TableData['meta'] | undefined;
  19. data: TableData['data'] | undefined;
  20. className?: string;
  21. getCustomFieldRenderer?: typeof getFieldRenderer;
  22. };
  23. class SimpleTableChart extends Component<Props> {
  24. renderRow(
  25. index: number,
  26. row: TableDataRow,
  27. tableMeta: NonNullable<TableData['meta']>,
  28. columns: ReturnType<typeof decodeColumnOrder>
  29. ) {
  30. const {location, organization, getCustomFieldRenderer} = this.props;
  31. return columns.map(column => {
  32. const fieldRenderer =
  33. getCustomFieldRenderer?.(column.name, tableMeta) ??
  34. getFieldRenderer(column.name, tableMeta);
  35. const rendered = fieldRenderer(row, {organization, location});
  36. return <TableCell key={`${index}:${column.name}`}>{rendered}</TableCell>;
  37. });
  38. }
  39. render() {
  40. const {className, loading, fields, metadata, data, title} = this.props;
  41. const meta = metadata ?? {};
  42. const columns = decodeColumnOrder(fields.map(field => ({field})));
  43. return (
  44. <Fragment>
  45. {title && <h4>{title}</h4>}
  46. <StyledPanelTable
  47. className={className}
  48. isLoading={loading}
  49. headers={columns.map((column, index) => {
  50. const align = fieldAlignment(column.name, column.type, meta);
  51. return (
  52. <HeadCell key={index} align={align}>
  53. {column.name}
  54. </HeadCell>
  55. );
  56. })}
  57. isEmpty={!data?.length}
  58. disablePadding
  59. >
  60. {data?.map((row, index) => this.renderRow(index, row, meta, columns))}
  61. </StyledPanelTable>
  62. </Fragment>
  63. );
  64. }
  65. }
  66. const StyledPanelTable = styled(PanelTable)`
  67. border-radius: 0;
  68. border-left: 0;
  69. border-right: 0;
  70. border-bottom: 0;
  71. margin: 0;
  72. ${/* sc-selector */ PanelTableHeader} {
  73. height: min-content;
  74. }
  75. `;
  76. type HeadCellProps = {
  77. align: string | undefined;
  78. };
  79. const HeadCell = styled('div')<HeadCellProps>`
  80. ${(p: HeadCellProps) => (p.align ? `text-align: ${p.align};` : '')}
  81. padding: ${space(1)} ${space(3)};
  82. `;
  83. const TableCell = styled('div')`
  84. padding: ${space(1)} ${space(3)};
  85. `;
  86. export default withOrganization(SimpleTableChart);