|
1 |
| -import type {HTMLAttributes, ReactNode} from 'react'; |
2 | 1 | import styled from '@emotion/styled';
|
3 | 2 |
|
4 | 3 | import {Alert} from 'sentry/components/core/alert';
|
5 | 4 | import InteractionStateLayer from 'sentry/components/core/interactionStateLayer';
|
6 |
| -import {Tooltip} from 'sentry/components/core/tooltip'; |
7 | 5 | import LoadingIndicator from 'sentry/components/loadingIndicator';
|
8 | 6 | import type {ReplayTableColumn} from 'sentry/components/replays/table/replayTableColumns';
|
9 |
| -import {ReplaySessionColumn} from 'sentry/components/replays/table/replayTableColumns'; |
| 7 | +import ReplayTableHeader from 'sentry/components/replays/table/replayTableHeader'; |
10 | 8 | import {SimpleTable} from 'sentry/components/tables/simpleTable';
|
11 | 9 | import {t} from 'sentry/locale';
|
12 | 10 | import type {Sort} from 'sentry/utils/discover/fields';
|
@@ -40,46 +38,42 @@ export default function ReplayTable({
|
40 | 38 | showDropdownFilters,
|
41 | 39 | sort,
|
42 | 40 | }: Props) {
|
| 41 | + const gridTemplateColumns = columns.map(col => col.width ?? 'max-content').join(' '); |
| 42 | + |
43 | 43 | if (isPending) {
|
44 | 44 | return (
|
45 |
| - <ReplayTableWithColumns |
| 45 | + <StyledSimpleTable |
46 | 46 | data-test-id="replay-table-loading"
|
47 |
| - columns={columns} |
48 |
| - sort={sort} |
49 |
| - onSortClick={onSortClick} |
| 47 | + style={{gridTemplateColumns}} |
50 | 48 | >
|
| 49 | + <ReplayTableHeader columns={columns} onSortClick={onSortClick} sort={sort} /> |
51 | 50 | <SimpleTable.Empty>
|
52 | 51 | <LoadingIndicator />
|
53 | 52 | </SimpleTable.Empty>
|
54 |
| - </ReplayTableWithColumns> |
| 53 | + </StyledSimpleTable> |
55 | 54 | );
|
56 | 55 | }
|
57 | 56 |
|
58 | 57 | if (error) {
|
59 | 58 | return (
|
60 |
| - <ReplayTableWithColumns |
| 59 | + <StyledSimpleTable |
61 | 60 | data-test-id="replay-table-errored"
|
62 |
| - columns={columns} |
63 |
| - sort={sort} |
64 |
| - onSortClick={onSortClick} |
| 61 | + style={{gridTemplateColumns}} |
65 | 62 | >
|
| 63 | + <ReplayTableHeader columns={columns} onSortClick={onSortClick} sort={sort} /> |
66 | 64 | <SimpleTable.Empty>
|
67 | 65 | <Alert type="error" showIcon>
|
68 | 66 | {t('Sorry, the list of replays could not be loaded. ')}
|
69 | 67 | {getErrorMessage(error)}
|
70 | 68 | </Alert>
|
71 | 69 | </SimpleTable.Empty>
|
72 |
| - </ReplayTableWithColumns> |
| 70 | + </StyledSimpleTable> |
73 | 71 | );
|
74 | 72 | }
|
75 | 73 |
|
76 | 74 | return (
|
77 |
| - <ReplayTableWithColumns |
78 |
| - data-test-id="replay-table" |
79 |
| - columns={columns} |
80 |
| - sort={sort} |
81 |
| - onSortClick={onSortClick} |
82 |
| - > |
| 75 | + <StyledSimpleTable data-test-id="replay-table" style={{gridTemplateColumns}}> |
| 76 | + <ReplayTableHeader columns={columns} onSortClick={onSortClick} sort={sort} /> |
83 | 77 | {replays.length === 0 && (
|
84 | 78 | <SimpleTable.Empty>{t('No replays found')}</SimpleTable.Empty>
|
85 | 79 | )}
|
@@ -110,57 +104,18 @@ export default function ReplayTable({
|
110 | 104 | </SimpleTable.Row>
|
111 | 105 | );
|
112 | 106 | })}
|
113 |
| - </ReplayTableWithColumns> |
| 107 | + </StyledSimpleTable> |
114 | 108 | );
|
115 | 109 | }
|
116 | 110 |
|
117 |
| -type TableProps = { |
118 |
| - children: ReactNode; |
119 |
| - columns: readonly ReplayTableColumn[]; |
120 |
| - onSortClick?: (key: string) => void; |
121 |
| - sort?: Sort; |
122 |
| -} & HTMLAttributes<HTMLTableElement>; |
123 |
| - |
124 |
| -const ReplayTableWithColumns = styled( |
125 |
| - ({children, columns, onSortClick, sort, ...props}: TableProps) => ( |
126 |
| - <SimpleTable {...props}> |
127 |
| - <SimpleTable.Header> |
128 |
| - {columns.map((column, columnIndex) => ( |
129 |
| - <SimpleTable.HeaderCell |
130 |
| - key={`${column.name}-${columnIndex}`} |
131 |
| - handleSortClick={() => column.sortKey && onSortClick?.(column.sortKey)} |
132 |
| - sort={ |
133 |
| - column.sortKey && sort?.field === column.sortKey ? sort.kind : undefined |
134 |
| - } |
135 |
| - > |
136 |
| - <Tooltip title={column.tooltip} disabled={!column.tooltip}> |
137 |
| - {column.name} |
138 |
| - </Tooltip> |
139 |
| - </SimpleTable.HeaderCell> |
140 |
| - ))} |
141 |
| - </SimpleTable.Header> |
142 |
| - |
143 |
| - {children} |
144 |
| - </SimpleTable> |
145 |
| - ) |
146 |
| -)` |
147 |
| - ${p => getGridTemplateColumns(p.columns)} |
148 |
| - margin-bottom: 0; |
| 111 | +const StyledSimpleTable = styled(SimpleTable)` |
149 | 112 | overflow: auto;
|
150 | 113 |
|
151 | 114 | [data-clickable='true'] {
|
152 | 115 | cursor: pointer;
|
153 | 116 | }
|
154 | 117 | `;
|
155 | 118 |
|
156 |
| -function getGridTemplateColumns(columns: readonly ReplayTableColumn[]) { |
157 |
| - return `grid-template-columns: ${columns |
158 |
| - .map(column => |
159 |
| - column === ReplaySessionColumn ? 'minmax(150px, 1fr)' : 'max-content' |
160 |
| - ) |
161 |
| - .join(' ')};`; |
162 |
| -} |
163 |
| - |
164 | 119 | function getErrorMessage(fetchError: RequestError) {
|
165 | 120 | if (typeof fetchError === 'string') {
|
166 | 121 | return fetchError;
|
@@ -193,7 +148,13 @@ const RowCell = styled(SimpleTable.RowCell)`
|
193 | 148 | position: relative;
|
194 | 149 | overflow: auto;
|
195 | 150 |
|
| 151 | + /* Used for cell menu items that are hidden by default */ |
196 | 152 | &:hover [data-visible-on-hover='true'] {
|
197 | 153 | opacity: 1;
|
198 | 154 | }
|
| 155 | +
|
| 156 | + /* Used for the main replay display name in ReplaySessionColumn */ |
| 157 | + &:hover [data-underline-on-hover='true'] { |
| 158 | + text-decoration: underline; |
| 159 | + } |
199 | 160 | `;
|
0 commit comments