@@ -6,11 +6,12 @@ import qs from "query-string";
6
6
import * as React from "react" ;
7
7
import { QueryClient , QueryClientProvider } from "react-query" ;
8
8
import {
9
- Redirect ,
9
+ Routes ,
10
10
Route ,
11
- BrowserRouter as Router ,
12
- Switch ,
13
- } from "react-router-dom" ;
11
+ BrowserRouter ,
12
+ useLocation ,
13
+ Navigate ,
14
+ } from "react-router" ;
14
15
import { ToastContainer } from "react-toastify" ;
15
16
import "react-toastify/dist/ReactToastify.css" ;
16
17
import { ThemeProvider } from "styled-components" ;
@@ -31,6 +32,10 @@ import AppContextProvider, {
31
32
} from "./contexts/AppContext" ;
32
33
import AuthContextProvider , { AuthCheck } from "./contexts/AuthContext" ;
33
34
import CoreClientContextProvider from "./contexts/CoreClientContext" ;
35
+ import {
36
+ LinkResolverProvider ,
37
+ useLinkResolver ,
38
+ } from "./contexts/LinkResolverContext" ;
34
39
import { useFeatureFlags } from "./hooks/featureflags" ;
35
40
import useNavigation from "./hooks/navigation" ;
36
41
import { useInDarkMode } from "./hooks/theme" ;
@@ -62,13 +67,17 @@ import UserInfo from "./pages/v2/UserInfo";
62
67
63
68
const queryClient = new QueryClient ( ) ;
64
69
65
- function withSearchParams ( Cmp ) {
66
- return ( { location : { search } , ...rest } ) => {
67
- const params = qs . parse ( search ) ;
70
+ const WithSearchParams = ( {
71
+ component : Component ,
72
+ ...props
73
+ } : {
74
+ component : React . FunctionComponent < any > ;
75
+ } ) => {
76
+ const location = useLocation ( ) ;
77
+ const params = qs . parse ( location . search ) ;
68
78
69
- return < Cmp { ...rest } { ...params } /> ;
70
- } ;
71
- }
79
+ return < Component { ...props } { ...params } /> ;
80
+ } ;
72
81
73
82
function getRuntimeNavItem ( isNewRuntimeEnabled : boolean ) : NavItem {
74
83
if ( isNewRuntimeEnabled ) {
@@ -144,79 +153,146 @@ const App = () => {
144
153
< PendoContainer />
145
154
146
155
< ErrorBoundary >
147
- < Switch >
148
- < Route exact path = { V2Routes . Automations } component = { Automations } />
149
- < Route
150
- path = { V2Routes . Kustomization }
151
- component = { withSearchParams ( KustomizationPage ) }
152
- />
153
- < Route path = { V2Routes . Sources } component = { Sources } />
154
- < Route
155
- path = { V2Routes . ImageAutomation }
156
- component = { ImageAutomationPage }
157
- />
158
- < Route
159
- path = { V2Routes . ImageAutomationUpdatesDetails }
160
- component = { withSearchParams ( ImageAutomationUpdatesDetails ) }
161
- />
162
- < Route
163
- path = { V2Routes . ImageAutomationRepositoryDetails }
164
- component = { withSearchParams ( ImageAutomationRepoDetails ) }
165
- />
166
- < Route
167
- path = { V2Routes . ImagePolicyDetails }
168
- component = { withSearchParams ( ImagePolicyDetails ) }
169
- />
156
+ < Routes >
157
+ < Route path = { V2Routes . Automations } element = { < Automations /> } />
158
+ < Route path = { V2Routes . Kustomization } >
159
+ < Route
160
+ element = { < WithSearchParams component = { KustomizationPage } /> }
161
+ index
162
+ path = "*"
163
+ />
164
+ </ Route >
165
+
166
+ < Route path = { V2Routes . Sources } >
167
+ < Route
168
+ element = { < WithSearchParams component = { Sources } /> }
169
+ index
170
+ path = "*"
171
+ />
172
+ </ Route >
173
+
174
+ < Route path = { V2Routes . ImageAutomation } >
175
+ < Route
176
+ element = { < WithSearchParams component = { ImageAutomationPage } /> }
177
+ index
178
+ path = "*"
179
+ />
180
+ </ Route >
181
+
182
+ < Route path = { V2Routes . ImageAutomationUpdatesDetails } >
183
+ < Route
184
+ element = {
185
+ < WithSearchParams component = { ImageAutomationUpdatesDetails } />
186
+ }
187
+ index
188
+ path = "*"
189
+ />
190
+ </ Route >
191
+
192
+ < Route path = { V2Routes . ImageAutomationRepositoryDetails } >
193
+ < Route
194
+ element = {
195
+ < WithSearchParams component = { ImageAutomationRepoDetails } />
196
+ }
197
+ index
198
+ path = "*"
199
+ />
200
+ </ Route >
201
+
202
+ < Route path = { V2Routes . ImagePolicyDetails } >
203
+ < Route
204
+ element = { < WithSearchParams component = { ImagePolicyDetails } /> }
205
+ index
206
+ path = "*"
207
+ />
208
+ </ Route >
209
+
170
210
{ isNewRuntimeEnabled ? (
171
- < Route path = { V2Routes . Runtime } component = { Runtime } />
211
+ < Route path = { V2Routes . Runtime } >
212
+ < Route index path = "*" element = { < Runtime /> } />
213
+ </ Route >
172
214
) : (
173
- < Route path = { V2Routes . FluxRuntime } component = { FluxRuntime } />
215
+ < Route path = { V2Routes . FluxRuntime } >
216
+ < Route index path = "*" element = { < FluxRuntime /> } />
217
+ </ Route >
174
218
) }
219
+
220
+ < Route path = { V2Routes . GitRepo } >
221
+ < Route
222
+ element = { < WithSearchParams component = { GitRepositoryDetail } /> }
223
+ index
224
+ path = "*"
225
+ />
226
+ </ Route >
227
+ < Route path = { V2Routes . HelmRepo } >
228
+ < Route
229
+ element = { < WithSearchParams component = { HelmRepositoryDetail } /> }
230
+ index
231
+ path = "*"
232
+ />
233
+ </ Route >
234
+ < Route path = { V2Routes . Bucket } >
235
+ < Route
236
+ element = { < WithSearchParams component = { BucketDetail } /> }
237
+ index
238
+ path = "*"
239
+ />
240
+ </ Route >
241
+ < Route path = { V2Routes . HelmRelease } >
242
+ < Route
243
+ element = { < WithSearchParams component = { HelmReleasePage } /> }
244
+ index
245
+ path = "*"
246
+ />
247
+ </ Route >
248
+ < Route path = { V2Routes . HelmChart } >
249
+ < Route
250
+ element = { < WithSearchParams component = { HelmChartDetail } /> }
251
+ index
252
+ path = "*"
253
+ />
254
+ </ Route >
255
+ < Route path = { V2Routes . OCIRepository } >
256
+ < Route
257
+ element = { < WithSearchParams component = { OCIRepositoryPage } /> }
258
+ index
259
+ path = "*"
260
+ />
261
+ </ Route >
262
+ < Route path = { V2Routes . Notifications } >
263
+ < Route
264
+ element = { < WithSearchParams component = { Notifications } /> }
265
+ index
266
+ path = "*"
267
+ />
268
+ </ Route >
269
+ < Route path = { V2Routes . Provider } >
270
+ < Route
271
+ element = { < WithSearchParams component = { ProviderPage } /> }
272
+ index
273
+ path = "*"
274
+ />
275
+ </ Route >
276
+ < Route path = { V2Routes . PolicyViolationDetails } >
277
+ < Route
278
+ element = { < WithSearchParams component = { PolicyViolationPage } /> }
279
+ index
280
+ path = "*"
281
+ />
282
+ </ Route >
283
+
284
+ < Route path = { V2Routes . UserInfo } element = { < UserInfo /> } />
285
+ < Route path = { V2Routes . Policies } element = { < PoliciesList /> } />
175
286
< Route
176
- path = { V2Routes . GitRepo }
177
- component = { withSearchParams ( GitRepositoryDetail ) }
178
- />
179
- < Route
180
- path = { V2Routes . HelmRepo }
181
- component = { withSearchParams ( HelmRepositoryDetail ) }
182
- />
183
- < Route
184
- path = { V2Routes . Bucket }
185
- component = { withSearchParams ( BucketDetail ) }
186
- />
187
- < Route
188
- path = { V2Routes . HelmRelease }
189
- component = { withSearchParams ( HelmReleasePage ) }
190
- />
191
- < Route
192
- path = { V2Routes . HelmChart }
193
- component = { withSearchParams ( HelmChartDetail ) }
194
- />
195
- < Route
196
- path = { V2Routes . OCIRepository }
197
- component = { withSearchParams ( OCIRepositoryPage ) }
198
- />
199
- < Route
200
- path = { V2Routes . Notifications }
201
- component = { withSearchParams ( Notifications ) }
202
- />
203
- < Route
204
- path = { V2Routes . Provider }
205
- component = { withSearchParams ( ProviderPage ) }
206
- />
207
- < Route
208
- path = { V2Routes . PolicyViolationDetails }
209
- component = { withSearchParams ( PolicyViolationPage ) }
287
+ element = { < WithSearchParams component = { PolicyDetailsPage } /> }
288
+ path = { V2Routes . PolicyDetailsPage }
210
289
/>
211
- < Route path = { V2Routes . UserInfo } component = { UserInfo } />
212
- < Route path = { V2Routes . Policies } component = { PoliciesList } />
213
290
< Route
214
- path = { V2Routes . PolicyDetailsPage }
215
- component = { withSearchParams ( PolicyDetailsPage ) }
291
+ element = { < Navigate to = { V2Routes . Automations } replace /> }
292
+ path = "/"
216
293
/>
217
- < Redirect exact from = "/" to = { V2Routes . Automations } />
218
- < Route exact path = "*" component = { Error } />
219
- </ Switch >
294
+ < Route path = "*" element = { Error } />
295
+ </ Routes >
220
296
</ ErrorBoundary >
221
297
< ToastContainer
222
298
position = "top-center"
@@ -246,30 +322,38 @@ const StylesProvider = ({ children }) => {
246
322
} ;
247
323
248
324
export default function AppContainer ( ) {
325
+ const resolver = useLinkResolver ( ) ;
249
326
return (
250
327
< QueryClientProvider client = { queryClient } >
251
- < Router basename = { getBasePath ( ) } >
328
+ < BrowserRouter basename = { getBasePath ( ) } >
252
329
< AppContextProvider footer = { < Footer /> } >
253
330
< StylesProvider >
254
331
< AuthContextProvider >
255
332
< CoreClientContextProvider api = { Core } >
256
- < Switch >
257
- { /* <Signin> does not use the base page <Layout> so pull it up here */ }
258
- < Route exact path = "/sign_in" >
259
- < SignIn />
260
- </ Route >
261
- < Route path = "*" >
333
+ < LinkResolverProvider resolver = { resolver } >
334
+ < Routes >
335
+ < Route element = { < SignIn /> } path = "/sign_in" />
262
336
{ /* Check we've got a logged in user otherwise redirect back to signin */ }
263
- < AuthCheck >
264
- < App />
265
- </ AuthCheck >
266
- </ Route >
267
- </ Switch >
337
+ < Route
338
+ path = "*"
339
+ element = {
340
+ < AuthCheck >
341
+ < App />
342
+ </ AuthCheck >
343
+ }
344
+ />
345
+ </ Routes >
346
+ < ToastContainer
347
+ position = "top-center"
348
+ autoClose = { 5000 }
349
+ newestOnTop = { false }
350
+ />
351
+ </ LinkResolverProvider >
268
352
</ CoreClientContextProvider >
269
353
</ AuthContextProvider >
270
354
</ StylesProvider >
271
355
</ AppContextProvider >
272
- </ Router >
356
+ </ BrowserRouter >
273
357
</ QueryClientProvider >
274
358
) ;
275
359
}
0 commit comments