77 */
88import { type LoaderFunctionArgs } from 'react-router'
99
10- import { apiQueryClient , queryClient , usePrefetchedApiQuery } from '@oxide/api'
11- import { Cloud16Icon , Cloud24Icon , NextArrow12Icon } from '@oxide/design-system/icons/react'
10+ import { Cloud16Icon , Cloud24Icon } from '@oxide/design-system/icons/react'
1211
12+ import { apiq , queryClient , usePrefetchedQuery } from '~/api'
1313import { DocsPopover } from '~/components/DocsPopover'
14- import { QueryParamTabs } from '~/components/QueryParamTabs '
14+ import { RouteTabs , Tab } from '~/components/RouteTabs '
1515import { makeCrumb } from '~/hooks/use-crumbs'
1616import { getSiloSelector , useSiloSelector } from '~/hooks/use-params'
17- import { Badge } from '~/ui/lib/Badge'
18- import { EmptyMessage } from '~/ui/lib/EmptyMessage'
1917import { PageHeader , PageTitle } from '~/ui/lib/PageHeader'
2018import { PropertiesTable } from '~/ui/lib/PropertiesTable'
21- import { TableEmptyBox } from '~/ui/lib/Table'
22- import { Tabs } from '~/ui/lib/Tabs'
2319import { docLinks } from '~/util/links'
24-
25- import { siloIdpList , SiloIdpsTab } from './SiloIdpsTab'
26- import { siloIpPoolsQuery , SiloIpPoolsTab } from './SiloIpPoolsTab'
27- import { SiloQuotasTab } from './SiloQuotasTab'
20+ import { pb } from '~/util/path-builder'
2821
2922export async function clientLoader ( { params } : LoaderFunctionArgs ) {
3023 const { silo } = getSiloSelector ( params )
31- await Promise . all ( [
32- apiQueryClient . prefetchQuery ( 'siloView' , { path : { silo } } ) ,
33- apiQueryClient . prefetchQuery ( 'siloUtilizationView' , { path : { silo } } ) ,
34- queryClient . prefetchQuery ( siloIdpList ( silo ) . optionsFn ( ) ) ,
35- queryClient . prefetchQuery ( siloIpPoolsQuery ( silo ) . optionsFn ( ) ) ,
36- ] )
24+ await queryClient . prefetchQuery ( apiq ( 'siloView' , { path : { silo } } ) )
3725 return null
3826}
3927
@@ -42,12 +30,7 @@ export const handle = makeCrumb((p) => p.silo!)
4230export default function SiloPage ( ) {
4331 const siloSelector = useSiloSelector ( )
4432
45- const { data : silo } = usePrefetchedApiQuery ( 'siloView' , { path : siloSelector } )
46-
47- const roleMapPairs = Object . entries ( silo . mappedFleetRoles ) . flatMap (
48- ( [ fleetRole , siloRoles ] ) =>
49- siloRoles . map ( ( siloRole ) => [ siloRole , fleetRole ] as [ string , string ] )
50- )
33+ const { data : silo } = usePrefetchedQuery ( apiq ( 'siloView' , { path : siloSelector } ) )
5134
5235 return (
5336 < >
@@ -73,50 +56,12 @@ export default function SiloPage() {
7356 < PropertiesTable . DateRow date = { silo . timeModified } label = "Last Modified" />
7457 </ PropertiesTable >
7558
76- < QueryParamTabs className = "full-width" defaultValue = "idps" >
77- < Tabs . List >
78- < Tabs . Trigger value = "idps" > Identity Providers</ Tabs . Trigger >
79- < Tabs . Trigger value = "ip-pools" > IP Pools</ Tabs . Trigger >
80- < Tabs . Trigger value = "quotas" > Quotas</ Tabs . Trigger >
81- < Tabs . Trigger value = "fleet-roles" > Fleet roles</ Tabs . Trigger >
82- </ Tabs . List >
83- < Tabs . Content value = "idps" >
84- < SiloIdpsTab />
85- </ Tabs . Content >
86- < Tabs . Content value = "ip-pools" >
87- < SiloIpPoolsTab />
88- </ Tabs . Content >
89- < Tabs . Content value = "quotas" >
90- < SiloQuotasTab />
91- </ Tabs . Content >
92- < Tabs . Content value = "fleet-roles" >
93- { /* TODO: better empty state explaining that no roles are mapped so nothing will happen */ }
94- { roleMapPairs . length === 0 ? (
95- < TableEmptyBox >
96- < EmptyMessage
97- icon = { < Cloud24Icon /> }
98- title = "Mapped fleet roles"
99- body = "Silo roles can automatically grant a fleet role. This silo has no role mappings configured."
100- />
101- </ TableEmptyBox >
102- ) : (
103- < >
104- < p className = "mb-4 text-default" >
105- Silo roles can automatically grant a fleet role.
106- </ p >
107- < ul className = "space-y-3" >
108- { roleMapPairs . map ( ( [ siloRole , fleetRole ] ) => (
109- < li key = { siloRole + '|' + fleetRole } className = "flex items-center" >
110- < Badge > Silo { siloRole } </ Badge >
111- < NextArrow12Icon className = "mx-3 text-default" aria-label = "maps to" />
112- < span className = "text-sans-md text-default" > Fleet { fleetRole } </ span >
113- </ li >
114- ) ) }
115- </ ul >
116- </ >
117- ) }
118- </ Tabs . Content >
119- </ QueryParamTabs >
59+ < RouteTabs fullWidth >
60+ < Tab to = { pb . siloIdps ( siloSelector ) } > Identity Providers</ Tab >
61+ < Tab to = { pb . siloIpPools ( siloSelector ) } > IP Pools</ Tab >
62+ < Tab to = { pb . siloQuotas ( siloSelector ) } > Quotas</ Tab >
63+ < Tab to = { pb . siloFleetRoles ( siloSelector ) } > Fleet roles</ Tab >
64+ </ RouteTabs >
12065 </ >
12166 )
12267}
0 commit comments