diff --git a/app/components/RouteTabs.tsx b/app/components/RouteTabs.tsx
index b1c0b3b39..8e9e5e7a4 100644
--- a/app/components/RouteTabs.tsx
+++ b/app/components/RouteTabs.tsx
@@ -84,11 +84,11 @@ export interface TabProps {
* able to link directly to the first sidebar tab, but we of course also want
* this tab to appear active for all the sidebar tabs. See instance metrics.
*/
- toPrefix?: string
+ activePrefix?: string
children: ReactNode
}
-export const Tab = ({ to, toPrefix, children }: TabProps) => {
- const isActive = useIsActivePath({ to: toPrefix || to })
+export const Tab = ({ to, activePrefix, children }: TabProps) => {
+ const isActive = useIsActivePath({ to: activePrefix || to })
return (
(
)
-export const NavLinkItem = (props: {
+type NavLinkProps = {
to: string
children: React.ReactNode
end?: boolean
disabled?: boolean
-}) => {
+ // Only for cases where we want to spoof the path and pretend 'isActive'
+ activePrefix?: string
+}
+
+export const NavLinkItem = ({
+ to,
+ children,
+ end,
+ disabled,
+ activePrefix,
+}: NavLinkProps) => {
// If the current page is the create form for this NavLinkItem's resource, highlight the NavLink in the sidebar
- const currentPathIsCreateForm = useLocation().pathname.startsWith(`${props.to}-new`)
+ const currentPathIsCreateForm = useLocation().pathname.startsWith(`${to}-new`)
+ // We aren't using NavLink, as we need to occasionally use an activePrefix to create an active state for matching root paths
+ // so we also recreate the isActive logic here
+ const isActive = useIsActivePath({ to: activePrefix || to, end })
return (
-
- cn(linkStyles, {
- 'text-accent !bg-accent-secondary hover:!bg-accent-secondary-hover [&>svg]:!text-accent-tertiary':
- isActive || currentPathIsCreateForm,
- 'pointer-events-none text-disabled': props.disabled,
- })
- }
- end={props.end}
+ svg]:!text-accent-tertiary':
+ isActive || currentPathIsCreateForm,
+ 'pointer-events-none text-disabled': disabled,
+ })}
+ aria-current={isActive ? 'page' : undefined}
>
- {props.children}
-
+ {children}
+
)
}
diff --git a/app/layouts/SystemLayout.tsx b/app/layouts/SystemLayout.tsx
index c85680d7b..df120206b 100644
--- a/app/layouts/SystemLayout.tsx
+++ b/app/layouts/SystemLayout.tsx
@@ -22,7 +22,7 @@ import { TopBar } from '~/components/TopBar'
import { useCurrentUser } from '~/hooks/use-current-user'
import { useQuickActions } from '~/hooks/use-quick-actions'
import { Divider } from '~/ui/lib/Divider'
-import { pb } from '~/util/path-builder'
+import { inventoryBase, pb } from '~/util/path-builder'
import { ContentPane, PageContainer } from './helpers'
@@ -102,7 +102,7 @@ export default function SystemLayout() {
Utilization
-
+
Inventory
diff --git a/app/pages/project/instances/InstancePage.tsx b/app/pages/project/instances/InstancePage.tsx
index 861a1553d..22e1ded89 100644
--- a/app/pages/project/instances/InstancePage.tsx
+++ b/app/pages/project/instances/InstancePage.tsx
@@ -258,7 +258,7 @@ export default function InstancePage() {
Networking
Metrics
diff --git a/app/pages/system/inventory/SledsTab.tsx b/app/pages/system/inventory/SledsTab.tsx
index 68b94f344..3358a78d8 100644
--- a/app/pages/system/inventory/SledsTab.tsx
+++ b/app/pages/system/inventory/SledsTab.tsx
@@ -40,7 +40,7 @@ export const handle = { crumb: 'Sleds' }
const colHelper = createColumnHelper()
const staticCols = [
colHelper.accessor('id', {
- cell: makeLinkCell((sledId) => pb.sled({ sledId })),
+ cell: makeLinkCell((sledId) => pb.sledInstances({ sledId })),
}),
// TODO: colHelper.accessor('baseboard.serviceAddress', { header: 'service address' }),
colHelper.group({
diff --git a/app/pages/system/inventory/sled/SledPage.tsx b/app/pages/system/inventory/sled/SledPage.tsx
index fd90de5f1..116961691 100644
--- a/app/pages/system/inventory/sled/SledPage.tsx
+++ b/app/pages/system/inventory/sled/SledPage.tsx
@@ -28,7 +28,7 @@ export async function clientLoader({ params }: LoaderFunctionArgs) {
}
export const handle = makeCrumb(
(p) => truncate(p.sledId!, 12, 'middle'),
- (p) => pb.sled({ sledId: p.sledId! })
+ (p) => pb.sledInstances({ sledId: p.sledId! })
)
export default function SledPage() {
diff --git a/app/util/__snapshots__/path-builder.spec.ts.snap b/app/util/__snapshots__/path-builder.spec.ts.snap
index 18627378c..1efaa684a 100644
--- a/app/util/__snapshots__/path-builder.spec.ts.snap
+++ b/app/util/__snapshots__/path-builder.spec.ts.snap
@@ -529,24 +529,6 @@ exports[`breadcrumbs 2`] = `
"path": "/system/silos",
},
],
- "sled (/system/inventory/sleds/5c56b522-c9b8-49e4-9f9a-8d52a89ec3e0/instances)": [
- {
- "label": "Inventory",
- "path": "/system/inventory",
- },
- {
- "label": "Sleds",
- "path": "/system/inventory/sleds",
- },
- {
- "label": "5c56b…ec3e0",
- "path": "/system/inventory/sleds/5c56b522-c9b8-49e4-9f9a-8d52a89ec3e0/instances",
- },
- {
- "label": "Instances",
- "path": "/system/inventory/sleds/5c56b522-c9b8-49e4-9f9a-8d52a89ec3e0/instances",
- },
- ],
"sledInstances (/system/inventory/sleds/5c56b522-c9b8-49e4-9f9a-8d52a89ec3e0/instances)": [
{
"label": "Inventory",
diff --git a/app/util/path-builder.spec.ts b/app/util/path-builder.spec.ts
index cbdb90fb9..65744284d 100644
--- a/app/util/path-builder.spec.ts
+++ b/app/util/path-builder.spec.ts
@@ -81,7 +81,6 @@ test('path builder', () => {
"siloUtilization": "/utilization",
"silos": "/system/silos",
"silosNew": "/system/silos-new",
- "sled": "/system/inventory/sleds/5c56b522-c9b8-49e4-9f9a-8d52a89ec3e0/instances",
"sledInstances": "/system/inventory/sleds/5c56b522-c9b8-49e4-9f9a-8d52a89ec3e0/instances",
"sledInventory": "/system/inventory/sleds",
"snapshotImagesNew": "/projects/p/snapshots/sn/images-new",
diff --git a/app/util/path-builder.ts b/app/util/path-builder.ts
index 1e65f73fa..19c088773 100644
--- a/app/util/path-builder.ts
+++ b/app/util/path-builder.ts
@@ -15,9 +15,10 @@ const instanceBase = ({ project, instance }: PP.Instance) =>
`${pb.instances({ project })}/${instance}`
const vpcBase = ({ project, vpc }: PP.Vpc) => `${pb.vpcs({ project })}/${vpc}`
-/** Don't use this for links. only exported for use as toPrefix on metrics tab */
+/** Don't use these for links. only exported for use with activePrefix */
export const instanceMetricsBase = ({ project, instance }: PP.Instance) =>
`${instanceBase({ project, instance })}/metrics`
+export const inventoryBase = () => '/system/inventory'
export const pb = {
projects: () => `/projects`,
@@ -109,10 +110,9 @@ export const pb = {
ipPoolEdit: (params: PP.IpPool) => `${pb.ipPool(params)}/edit`,
ipPoolRangeAdd: (params: PP.IpPool) => `${pb.ipPool(params)}/ranges-add`,
- sledInventory: () => '/system/inventory/sleds',
- diskInventory: () => '/system/inventory/disks',
- sled: ({ sledId }: PP.Sled) => `/system/inventory/sleds/${sledId}/instances`,
- sledInstances: ({ sledId }: PP.Sled) => `/system/inventory/sleds/${sledId}/instances`,
+ sledInventory: () => `${inventoryBase()}/sleds`,
+ diskInventory: () => `${inventoryBase()}/disks`,
+ sledInstances: ({ sledId }: PP.Sled) => `${pb.sledInventory()}/${sledId}/instances`,
silos: () => '/system/silos',
silosNew: () => '/system/silos-new',