@@ -7,6 +7,7 @@ import Count from 'sentry/components/count';
7
7
import EmptyStateWarning , { EmptyStreamWrapper } from 'sentry/components/emptyStateWarning' ;
8
8
import ExternalLink from 'sentry/components/links/externalLink' ;
9
9
import LoadingIndicator from 'sentry/components/loadingIndicator' ;
10
+ import Pagination from 'sentry/components/pagination' ;
10
11
import PerformanceDuration from 'sentry/components/performanceDuration' ;
11
12
import { DEFAULT_PER_PAGE , SPAN_PROPS_DOCS_URL } from 'sentry/constants' ;
12
13
import { IconChevron } from 'sentry/icons/iconChevron' ;
@@ -15,6 +16,7 @@ import {t, tct} from 'sentry/locale';
15
16
import { space } from 'sentry/styles/space' ;
16
17
import { defined } from 'sentry/utils' ;
17
18
import { trackAnalytics } from 'sentry/utils/analytics' ;
19
+ import { decodeScalar } from 'sentry/utils/queryString' ;
18
20
import { useLocation } from 'sentry/utils/useLocation' ;
19
21
import useOrganization from 'sentry/utils/useOrganization' ;
20
22
import usePageFilters from 'sentry/utils/usePageFilters' ;
@@ -45,11 +47,16 @@ import {
45
47
export function TracesTable ( ) {
46
48
const [ dataset ] = useDataset ( ) ;
47
49
const [ query ] = useUserQuery ( ) ;
48
- const { data, isPending, isError} = useTraces ( {
50
+
51
+ const location = useLocation ( ) ;
52
+ const cursor = decodeScalar ( location . query . cursor ) ;
53
+
54
+ const { data, isPending, isError, getResponseHeader} = useTraces ( {
49
55
dataset,
50
56
query,
51
57
limit : DEFAULT_PER_PAGE ,
52
58
sort : '-timestamp' ,
59
+ cursor,
53
60
} ) ;
54
61
55
62
const showErrorState = useMemo ( ( ) => {
@@ -61,66 +68,69 @@ export function TracesTable() {
61
68
} , [ data , isPending , showErrorState ] ) ;
62
69
63
70
return (
64
- < StyledPanel >
65
- < TracePanelContent >
66
- < StyledPanelHeader align = "left" lightText >
67
- { t ( 'Trace ID' ) }
68
- </ StyledPanelHeader >
69
- < StyledPanelHeader align = "left" lightText >
70
- { t ( 'Trace Root' ) }
71
- </ StyledPanelHeader >
72
- < StyledPanelHeader align = "right" lightText >
73
- { ! query ? t ( 'Total Spans' ) : t ( 'Matching Spans' ) }
74
- </ StyledPanelHeader >
75
- < StyledPanelHeader align = "left" lightText >
76
- { t ( 'Timeline' ) }
77
- </ StyledPanelHeader >
78
- < StyledPanelHeader align = "right" lightText >
79
- { t ( 'Duration' ) }
80
- </ StyledPanelHeader >
81
- < StyledPanelHeader align = "right" lightText >
82
- { t ( 'Timestamp' ) }
83
- </ StyledPanelHeader >
84
- { isPending && (
85
- < StyledPanelItem span = { 6 } overflow >
86
- < LoadingIndicator />
87
- </ StyledPanelItem >
88
- ) }
89
- { showErrorState && ( // TODO: need an error state
90
- < StyledPanelItem span = { 7 } overflow >
91
- < EmptyStreamWrapper >
92
- < IconWarning color = "gray300" size = "lg" />
93
- </ EmptyStreamWrapper >
94
- </ StyledPanelItem >
95
- ) }
96
- { showEmptyState && (
97
- < StyledPanelItem span = { 7 } overflow >
98
- < EmptyStateWarning withIcon >
99
- < EmptyStateText size = "fontSizeExtraLarge" >
100
- { t ( 'No trace results found' ) }
101
- </ EmptyStateText >
102
- < EmptyStateText size = "fontSizeMedium" >
103
- { tct ( 'Try adjusting your filters or refer to [docSearchProps].' , {
104
- docSearchProps : (
105
- < ExternalLink href = { SPAN_PROPS_DOCS_URL } >
106
- { t ( 'docs for search properties' ) }
107
- </ ExternalLink >
108
- ) ,
109
- } ) }
110
- </ EmptyStateText >
111
- </ EmptyStateWarning >
112
- </ StyledPanelItem >
113
- ) }
114
- { data ?. data ?. map ( ( trace , i ) => (
115
- < TraceRow
116
- key = { trace . trace }
117
- trace = { trace }
118
- defaultExpanded = { query && i === 0 }
119
- query = { query }
120
- />
121
- ) ) }
122
- </ TracePanelContent >
123
- </ StyledPanel >
71
+ < Fragment >
72
+ < StyledPanel >
73
+ < TracePanelContent >
74
+ < StyledPanelHeader align = "left" lightText >
75
+ { t ( 'Trace ID' ) }
76
+ </ StyledPanelHeader >
77
+ < StyledPanelHeader align = "left" lightText >
78
+ { t ( 'Trace Root' ) }
79
+ </ StyledPanelHeader >
80
+ < StyledPanelHeader align = "right" lightText >
81
+ { ! query ? t ( 'Total Spans' ) : t ( 'Matching Spans' ) }
82
+ </ StyledPanelHeader >
83
+ < StyledPanelHeader align = "left" lightText >
84
+ { t ( 'Timeline' ) }
85
+ </ StyledPanelHeader >
86
+ < StyledPanelHeader align = "right" lightText >
87
+ { t ( 'Duration' ) }
88
+ </ StyledPanelHeader >
89
+ < StyledPanelHeader align = "right" lightText >
90
+ { t ( 'Timestamp' ) }
91
+ </ StyledPanelHeader >
92
+ { isPending && (
93
+ < StyledPanelItem span = { 6 } overflow >
94
+ < LoadingIndicator />
95
+ </ StyledPanelItem >
96
+ ) }
97
+ { showErrorState && ( // TODO: need an error state
98
+ < StyledPanelItem span = { 7 } overflow >
99
+ < EmptyStreamWrapper >
100
+ < IconWarning color = "gray300" size = "lg" />
101
+ </ EmptyStreamWrapper >
102
+ </ StyledPanelItem >
103
+ ) }
104
+ { showEmptyState && (
105
+ < StyledPanelItem span = { 7 } overflow >
106
+ < EmptyStateWarning withIcon >
107
+ < EmptyStateText size = "fontSizeExtraLarge" >
108
+ { t ( 'No trace results found' ) }
109
+ </ EmptyStateText >
110
+ < EmptyStateText size = "fontSizeMedium" >
111
+ { tct ( 'Try adjusting your filters or refer to [docSearchProps].' , {
112
+ docSearchProps : (
113
+ < ExternalLink href = { SPAN_PROPS_DOCS_URL } >
114
+ { t ( 'docs for search properties' ) }
115
+ </ ExternalLink >
116
+ ) ,
117
+ } ) }
118
+ </ EmptyStateText >
119
+ </ EmptyStateWarning >
120
+ </ StyledPanelItem >
121
+ ) }
122
+ { data ?. data ?. map ( ( trace , i ) => (
123
+ < TraceRow
124
+ key = { trace . trace }
125
+ trace = { trace }
126
+ defaultExpanded = { query && i === 0 }
127
+ query = { query }
128
+ />
129
+ ) ) }
130
+ </ TracePanelContent >
131
+ </ StyledPanel >
132
+ < Pagination pageLinks = { getResponseHeader ?.( 'Link' ) } />
133
+ </ Fragment >
124
134
) ;
125
135
}
126
136
0 commit comments