Skip to content

Commit 44255e7

Browse files
authored
fix: Seperate org name from error banner on 404 page (#3525)
1 parent 67b950a commit 44255e7

File tree

12 files changed

+735
-166
lines changed

12 files changed

+735
-166
lines changed

src/App.test.tsx

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
2+
import {
3+
QueryClientProvider as QueryClientProviderV5,
4+
QueryClient as QueryClientV5,
5+
} from '@tanstack/react-queryV5'
26
import { render, screen, waitFor } from '@testing-library/react'
37
import { graphql, http, HttpResponse } from 'msw'
48
import { setupServer } from 'msw/node'
@@ -121,32 +125,43 @@ const mockRepoOverview = {
121125
},
122126
}
123127

124-
const queryClient = new QueryClient({
125-
defaultOptions: {
126-
queries: {
127-
retry: false,
128+
const mockNavigatorData = {
129+
owner: {
130+
isCurrentUserPartOfOrg: true,
131+
repository: {
132+
__typename: 'Repository',
133+
name: 'test-repo',
128134
},
129135
},
136+
}
137+
138+
const queryClient = new QueryClient({
139+
defaultOptions: { queries: { retry: false } },
140+
})
141+
const queryClientV5 = new QueryClientV5({
142+
defaultOptions: { queries: { retry: false } },
130143
})
131144

132145
let testLocation: ReturnType<typeof useLocation>
133146
const wrapper =
134147
(initialEntries = ['']): React.FC<React.PropsWithChildren> =>
135148
({ children }) => (
136-
<QueryClientProvider client={queryClient}>
137-
<MemoryRouter initialEntries={initialEntries}>
138-
<Suspense fallback={<p>Loading</p>}>
139-
{children}
140-
<Route
141-
path="*"
142-
render={({ location }) => {
143-
testLocation = location
144-
return null
145-
}}
146-
/>
147-
</Suspense>
148-
</MemoryRouter>
149-
</QueryClientProvider>
149+
<QueryClientProviderV5 client={queryClientV5}>
150+
<QueryClientProvider client={queryClient}>
151+
<MemoryRouter initialEntries={initialEntries}>
152+
<Suspense fallback={<p>Loading</p>}>
153+
{children}
154+
<Route
155+
path="*"
156+
render={({ location }) => {
157+
testLocation = location
158+
return null
159+
}}
160+
/>
161+
</Suspense>
162+
</MemoryRouter>
163+
</QueryClientProvider>
164+
</QueryClientProviderV5>
150165
)
151166

152167
const server = setupServer()
@@ -231,6 +246,9 @@ describe('App', () => {
231246
}),
232247
graphql.query('GetUploadTokenRequired', (info) => {
233248
return HttpResponse.json({ data: { owner: null } })
249+
}),
250+
graphql.query('NavigatorData', () => {
251+
return HttpResponse.json({ data: mockNavigatorData })
234252
})
235253
)
236254
}

src/layouts/BaseLayout/BaseLayout.test.tsx

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
2+
import {
3+
QueryClientProvider as QueryClientProviderV5,
4+
QueryClient as QueryClientV5,
5+
} from '@tanstack/react-queryV5'
26
import { render, screen, waitFor } from '@testing-library/react'
37
import { graphql, http, HttpResponse } from 'msw'
48
import { setupServer } from 'msw/node'
@@ -156,34 +160,48 @@ const internalUserHasSyncedProviders = {
156160
termsAgreement: true,
157161
}
158162

163+
const mockNavigatorData = {
164+
owner: {
165+
isCurrentUserPartOfOrg: true,
166+
repository: {
167+
__typename: 'Repository',
168+
name: 'test-repo',
169+
},
170+
},
171+
}
172+
173+
const server = setupServer()
159174
const queryClient = new QueryClient({
160175
defaultOptions: {
161-
queries: {
162-
retry: false,
163-
suspense: false,
164-
},
176+
queries: { retry: false, suspense: false },
177+
},
178+
})
179+
const queryClientV5 = new QueryClientV5({
180+
defaultOptions: {
181+
queries: { retry: false },
165182
},
166183
})
167-
const server = setupServer()
168184

169185
let testLocation: ReturnType<typeof useLocation>
170186
const wrapper: (
171187
initialEntries?: string[]
172188
) => React.FC<React.PropsWithChildren> =
173189
(initialEntries = ['/bb/batman/batcave']) =>
174190
({ children }) => (
175-
<QueryClientProvider client={queryClient}>
176-
<MemoryRouter initialEntries={initialEntries}>
177-
<Route path="/:provider/:owner/:repo">{children}</Route>
178-
<Route
179-
path="*"
180-
render={({ location }) => {
181-
testLocation = location
182-
return null
183-
}}
184-
/>
185-
</MemoryRouter>
186-
</QueryClientProvider>
191+
<QueryClientProviderV5 client={queryClientV5}>
192+
<QueryClientProvider client={queryClient}>
193+
<MemoryRouter initialEntries={initialEntries}>
194+
<Route path="/:provider/:owner/:repo">{children}</Route>
195+
<Route
196+
path="*"
197+
render={({ location }) => {
198+
testLocation = location
199+
return null
200+
}}
201+
/>
202+
</MemoryRouter>
203+
</QueryClientProvider>
204+
</QueryClientProviderV5>
187205
)
188206

189207
beforeAll(() => {
@@ -192,6 +210,7 @@ beforeAll(() => {
192210

193211
afterEach(() => {
194212
queryClient.clear()
213+
queryClientV5.clear()
195214
server.resetHandlers()
196215
vi.clearAllMocks()
197216
})
@@ -236,7 +255,7 @@ describe('BaseLayout', () => {
236255
}),
237256
// Self hosted only
238257
graphql.query('HasAdmins', (info) => {
239-
return HttpResponse.json({ data: {} })
258+
return HttpResponse.json({ data: { config: null } })
240259
}),
241260
graphql.query('Seats', (info) => {
242261
return HttpResponse.json({ data: {} })
@@ -261,6 +280,9 @@ describe('BaseLayout', () => {
261280
graphql.mutation('updateDefaultOrganization', (info) => {
262281
return HttpResponse.json({ data: {} })
263282
}),
283+
graphql.query('NavigatorData', () => {
284+
return HttpResponse.json({ data: mockNavigatorData })
285+
}),
264286
http.get('/internal/users/current', (info) => {
265287
return HttpResponse.json({})
266288
})

src/layouts/BaseLayout/BaseLayout.tsx

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import { useQuery as useQueryV5 } from '@tanstack/react-queryV5'
12
import { lazy, Suspense } from 'react'
2-
import { Redirect } from 'react-router-dom'
3+
import { Redirect, useParams } from 'react-router-dom'
34

45
import Footer from 'layouts/Footer'
56
import Header from 'layouts/Header'
@@ -14,6 +15,7 @@ import GlobalBanners from 'shared/GlobalBanners'
1415
import GlobalTopBanners from 'shared/GlobalTopBanners'
1516
import LoadingLogo from 'ui/LoadingLogo'
1617

18+
import { NavigatorDataQueryOpts } from './hooks/NavigatorDataQueryOpts'
1719
import { useUserAccessGate } from './hooks/useUserAccessGate'
1820

1921
const DefaultOrgSelector = lazy(() => import('pages/DefaultOrgSelector'))
@@ -65,19 +67,42 @@ function OnboardingOrChildren({
6567
return <>{children}</>
6668
}
6769

70+
interface URLParams {
71+
provider?: string
72+
owner?: string
73+
repo?: string
74+
}
75+
6876
function BaseLayout({ children }: React.PropsWithChildren) {
77+
const { provider, owner, repo } = useParams<URLParams>()
78+
useTracking()
79+
const { isImpersonating } = useImpersonate()
6980
const {
7081
isFullExperience,
7182
showAgreeToTerms,
7283
showDefaultOrgSelector,
7384
redirectToSyncPage,
74-
isLoading,
85+
isLoading: isUserAccessGateLoading,
7586
} = useUserAccessGate()
76-
useTracking()
77-
const { isImpersonating } = useImpersonate()
87+
88+
// we have to fetch the data for the navigator up here as we can't
89+
// conditionally call a suspense query, as well we need a way to have the
90+
// loader be shown while we're loading
91+
const { data, isLoading: isNavigatorDataLoading } = useQueryV5({
92+
enabled: !!provider && !!owner && !!repo,
93+
...NavigatorDataQueryOpts({
94+
// if these aren't provided, the query is disabled so we don't need to
95+
// worry about the empty strings causing errors
96+
provider: provider ?? '',
97+
owner: owner ?? '',
98+
repo: repo ?? '',
99+
}),
100+
})
78101

79102
// Pause rendering of a page till we know if the user is logged in or not
80-
if (isLoading) return <FullPageLoader />
103+
if (isUserAccessGateLoading || isNavigatorDataLoading) {
104+
return <FullPageLoader />
105+
}
81106

82107
return (
83108
<>
@@ -89,7 +114,7 @@ function BaseLayout({ children }: React.PropsWithChildren) {
89114
{isFullExperience || isImpersonating ? (
90115
<>
91116
<GlobalTopBanners />
92-
<Header />
117+
<Header hasRepoAccess={data?.hasRepoAccess} />
93118
</>
94119
) : (
95120
<>

0 commit comments

Comments
 (0)