@@ -16,7 +16,6 @@ import {IconAdd} from 'sentry/icons';
1616import { IconSearch } from 'sentry/icons/iconSearch' ;
1717import { t , tct } from 'sentry/locale' ;
1818import type { RepositoryWithSettings } from 'sentry/types/integrations' ;
19- import type { Sort } from 'sentry/utils/discover/fields' ;
2019import { ListItemCheckboxProvider } from 'sentry/utils/list/useListItemCheckboxState' ;
2120import { useInfiniteQuery , useQueryClient } from 'sentry/utils/queryClient' ;
2221import parseAsSort from 'sentry/utils/url/parseAsSort' ;
@@ -115,166 +114,99 @@ export default function SeerRepoTable() {
115114 } ,
116115 } ) ;
117116
118- if ( isPending ) {
119- return (
120- < RepoTable
121- mutateRepositorySettings = { mutateRepositorySettings }
122- onSortClick = { setSort }
123- isLoading = { isPending || isFetchingNextPage }
124- isLoadingMore = { false /* prevent redundant spinners */ }
125- repositories = { [ ] }
126- searchTerm = { searchTerm }
127- setSearchTerm = { setSearchTerm }
128- sort = { sort }
129- >
130- < SimpleTable . Empty >
131- < LoadingIndicator />
132- </ SimpleTable . Empty >
133- </ RepoTable >
134- ) ;
135- }
136-
137- if ( isError ) {
138- return (
139- < RepoTable
140- mutateRepositorySettings = { mutateRepositorySettings }
141- onSortClick = { setSort }
142- isLoading = { isPending || isFetchingNextPage }
143- isLoadingMore = { hasNextPage || isFetchingNextPage }
144- repositories = { [ ] }
145- searchTerm = { searchTerm }
146- setSearchTerm = { setSearchTerm }
147- sort = { sort }
148- >
149- < SimpleTable . Empty >
150- < LoadingError />
151- </ SimpleTable . Empty >
152- </ RepoTable >
153- ) ;
154- }
117+ const hits = repositories ?. length ?? 0 ;
118+ const hasData = hits > 0 ;
155119
156120 return (
157121 < ListItemCheckboxProvider
158- hits = { repositories . length }
159- knownIds = { repositories . map ( repository => repository . id ) }
122+ hits = { repositories ? .length ?? 0 }
123+ knownIds = { repositories ? .map ( repository => repository . id ) ?? [ ] }
160124 queryKey = { queryOptions . queryKey }
161125 >
162- < RepoTable
163- mutateRepositorySettings = { mutateRepositorySettings }
164- onSortClick = { setSort }
165- isLoading = { isPending || isFetchingNextPage }
166- isLoadingMore = { hasNextPage || isFetchingNextPage }
167- repositories = { repositories }
168- searchTerm = { searchTerm }
169- setSearchTerm = { setSearchTerm }
170- sort = { sort }
171- >
172- { repositories . length === 0 ? (
173- < SimpleTable . Empty >
174- { searchTerm
175- ? tct ( 'No repositories found matching [searchTerm]' , {
176- searchTerm : < code > { searchTerm } </ code > ,
177- } )
178- : t ( 'No repositories found' ) }
179- </ SimpleTable . Empty >
180- ) : (
181- repositories . map ( repository => (
182- < SeerRepoTableRow
183- key = { repository . id }
184- mutateRepositorySettings = { mutateRepositorySettings }
185- mutationData = { mutationData }
186- repository = { repository }
126+ < Stack gap = "lg" >
127+ < Grid
128+ minWidth = "0"
129+ gap = "md"
130+ columns = { hasData ? '1fr max-content' : '1fr max-content max-content' }
131+ >
132+ < InputGroup >
133+ < InputGroup . LeadingItems disablePointerEvents >
134+ < IconSearch />
135+ </ InputGroup . LeadingItems >
136+ < InputGroup . Input
137+ size = "md"
138+ disabled = { ! hasData }
139+ placeholder = { t ( 'Search' ) }
140+ value = { searchTerm ?? '' }
141+ onChange = { e =>
142+ setSearchTerm ( e . target . value , { limitUrlUpdates : debounce ( 125 ) } )
143+ }
187144 />
188- ) )
189- ) }
190- </ RepoTable >
191- </ ListItemCheckboxProvider >
192- ) ;
193- }
194-
195- function RepoTable ( {
196- children,
197- isLoading,
198- isLoadingMore,
199- mutateRepositorySettings,
200- onSortClick,
201- repositories,
202- searchTerm,
203- setSearchTerm,
204- sort,
205- } : {
206- children : React . ReactNode ;
207- isLoading : boolean ;
208- isLoadingMore : boolean ;
209- mutateRepositorySettings : ReturnType < typeof useBulkUpdateRepositorySettings > [ 'mutate' ] ;
210- onSortClick : ( sort : Sort ) => void ;
211- repositories : RepositoryWithSettings [ ] ;
212- searchTerm : string ;
213- setSearchTerm : ReturnType < typeof useQueryState < string > > [ 1 ] ;
214- sort : Sort ;
215- } ) {
216- const organization = useOrganization ( ) ;
217- const hasData = repositories . length > 0 ;
218- return (
219- < Stack gap = "lg" >
220- < Grid
221- minWidth = "0"
222- gap = "md"
223- columns = { hasData ? '1fr max-content' : '1fr max-content max-content' }
224- >
225- < InputGroup >
226- < InputGroup . LeadingItems disablePointerEvents >
227- < IconSearch />
228- </ InputGroup . LeadingItems >
229- < InputGroup . Input
230- size = "md"
231- disabled = { ! hasData }
232- placeholder = { t ( 'Search' ) }
233- value = { searchTerm ?? '' }
234- onChange = { e =>
235- setSearchTerm ( e . target . value , { limitUrlUpdates : debounce ( 125 ) } )
236- }
145+ </ InputGroup >
146+
147+ { hits > 0 ? null : < LoadingIndicator mini /> }
148+
149+ < LinkButton
150+ priority = "primary"
151+ icon = { < IconAdd /> }
152+ to = { {
153+ pathname : `/settings/${ organization . slug } /integrations/` ,
154+ query : {
155+ category : 'source code management' ,
156+ } ,
157+ } }
158+ >
159+ { t ( 'Add Repository' ) }
160+ </ LinkButton >
161+ </ Grid >
162+ < SimpleTableWithColumns >
163+ < SeerRepoTableHeader
164+ mutateRepositorySettings = { mutateRepositorySettings }
165+ onSortClick = { setSort }
166+ disabled = { isPending || isFetchingNextPage }
167+ hits = { hits }
168+ sort = { sort }
237169 />
238- </ InputGroup >
239-
240- { hasData ? null : < LoadingIndicator mini /> }
241-
242- < LinkButton
243- priority = "primary"
244- icon = { < IconAdd /> }
245- to = { {
246- pathname : `/settings/ ${ organization . slug } /integrations/` ,
247- query : {
248- category : 'source code management' ,
249- } ,
250- } }
251- >
252- { t ( 'Add Repository ' ) }
253- </ LinkButton >
254- </ Grid >
255-
256- < SimpleTableWithColumns >
257- < SeerRepoTableHeader
258- mutateRepositorySettings = { mutateRepositorySettings }
259- onSortClick = { onSortClick }
260- disabled = { isLoading }
261- repositories = { repositories }
262- sort = { sort }
263- />
264- { children }
265- { isLoadingMore ? (
266- < SimpleTable . Row key = "loading-row" >
267- < SimpleTable . RowCell
268- align = "center"
269- justify = "center"
270- style = { { gridColumn : '1 / -1' } }
271- >
272- < LoadingIndicator mini / >
273- </ SimpleTable . RowCell >
274- </ SimpleTable . Row >
275- ) : null }
276- </ SimpleTableWithColumns >
277- </ Stack >
170+ { isPending ? (
171+ < SimpleTable . Empty >
172+ < LoadingIndicator />
173+ </ SimpleTable . Empty >
174+ ) : isError ? (
175+ < SimpleTable . Empty >
176+ < LoadingError />
177+ </ SimpleTable . Empty >
178+ ) : repositories . length === 0 ? (
179+ < SimpleTable . Empty >
180+ { searchTerm
181+ ? tct ( 'No repositories found matching [searchTerm]' , {
182+ searchTerm : < code > { searchTerm } </ code > ,
183+ } )
184+ : t ( 'No repositories found ' ) }
185+ </ SimpleTable . Empty >
186+ ) : (
187+ repositories . map ( repository => (
188+ < SeerRepoTableRow
189+ key = { repository . id }
190+ mutateRepositorySettings = { mutateRepositorySettings }
191+ mutationData = { mutationData }
192+ repository = { repository }
193+ />
194+ ) )
195+ ) }
196+ { hasNextPage || isFetchingNextPage ? (
197+ < SimpleTable . Row key = "loading-row" >
198+ < SimpleTable . RowCell
199+ align = "center"
200+ justify = "center"
201+ style = { { gridColumn : '1 / -1' } }
202+ >
203+ < LoadingIndicator mini / >
204+ </ SimpleTable . RowCell >
205+ </ SimpleTable . Row >
206+ ) : null }
207+ </ SimpleTableWithColumns >
208+ </ Stack >
209+ </ ListItemCheckboxProvider >
278210 ) ;
279211}
280212
0 commit comments