Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/pages/system/inventory/SledsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { createColumnHelper } from '@tanstack/react-table'
import { api, getListQFn, queryClient, type Sled } from '@oxide/api'
import { Servers24Icon } from '@oxide/design-system/icons/react'

import { EmptyCell } from '~/table/cells/EmptyCell'
import { LinkCell } from '~/table/cells/LinkCell'
import { useQueryTable } from '~/table/QueryTable'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
Expand All @@ -29,6 +30,15 @@ export const handle = { crumb: 'Sleds' }

const colHelper = createColumnHelper<Sled>()
const staticCols = [
// last observed location, so null when a sled was just inserted.
// 0 is a valid slot, hence ?? instead of ||.
colHelper.accessor('slot', {
cell: (info) => (
<div className="w-[2.5ch] text-right tabular-nums">
{info.getValue() ?? <EmptyCell />}
</div>
),
}),
colHelper.accessor('id', {
cell: (info) => (
<LinkCell to={pb.sledInstances({ sledId: info.getValue() })}>
Expand All @@ -51,10 +61,12 @@ const staticCols = [
header: 'Policy',
columns: [
colHelper.accessor('policy', {
id: 'policyKind',
header: 'Kind',
cell: (info) => <SledKindBadge policy={info.getValue()} />,
}),
colHelper.accessor('policy', {
id: 'provisionPolicy',
header: 'Provision policy',
cell: (info) => <ProvisionPolicyBadge policy={info.getValue()} />,
}),
Expand Down
6 changes: 6 additions & 0 deletions app/pages/system/inventory/sled/SledPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Servers24Icon } from '@oxide/design-system/icons/react'
import { RouteTabs, Tab } from '~/components/RouteTabs'
import { makeCrumb } from '~/hooks/use-crumbs'
import { useSledParams } from '~/hooks/use-params'
import { EmptyCell } from '~/table/cells/EmptyCell'
import { PageHeader, PageTitle } from '~/ui/lib/PageHeader'
import { PropertiesTable } from '~/ui/lib/PropertiesTable'
import { truncate } from '~/ui/lib/Truncate'
Expand Down Expand Up @@ -71,6 +72,11 @@ export default function SledPage() {
label="usable physical ram"
bytes={sled.usablePhysicalRam}
/>
<PropertiesTable.Row label="slot">
{/* 0 is a valid slot, hence ?? instead of || */}
<span className="text-default">{sled.slot ?? <EmptyCell />}</span>
</PropertiesTable.Row>
<PropertiesTable.DateRow label="Created" date={sled.timeCreated} />
</PropertiesTable>

<RouteTabs fullWidth>
Expand Down
4 changes: 4 additions & 0 deletions mock-api/sled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const sleds: Json<Sled[]> = [
serial: 'BRM02222869',
revision: 0,
},
slot: 14,
usable_hardware_threads: 254,
usable_physical_ram: 1_099_511_627_776,
},
Expand All @@ -43,6 +44,7 @@ export const sleds: Json<Sled[]> = [
serial: 'BRM02222870',
revision: 0,
},
slot: 15,
usable_hardware_threads: 254,
usable_physical_ram: 1_099_511_627_776,
},
Expand All @@ -60,6 +62,7 @@ export const sleds: Json<Sled[]> = [
serial: 'BRM02222868',
revision: 0,
},
slot: 2,
usable_hardware_threads: 254,
usable_physical_ram: 1_099_511_627_776,
},
Expand All @@ -77,6 +80,7 @@ export const sleds: Json<Sled[]> = [
serial: 'BRM02222867',
revision: 0,
},
slot: null,
usable_hardware_threads: 254,
usable_physical_ram: 1_099_511_627_776,
},
Expand Down
3 changes: 3 additions & 0 deletions test/e2e/inventory.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ test('Sled inventory page', async ({ page }) => {
// grouping, hence the slightly weird column names
await expectRowVisible(sledsTable, {
id: expect.stringContaining(sleds[0].id),
slot: '14',
'serial number': sleds[0].baseboard.serial,
Kind: 'In service',
'Provision policy': 'Provisionable',
Expand All @@ -45,6 +46,7 @@ test('Sled inventory page', async ({ page }) => {
})
await expectRowVisible(sledsTable, {
id: expect.stringContaining(sleds[3].id),
slot: '—',
'serial number': sleds[3].baseboard.serial,
Kind: 'Expunged',
'Provision policy': '—',
Expand All @@ -56,6 +58,7 @@ test('Sled inventory page', async ({ page }) => {

await expectVisible(page, ['role=heading[name*="Sled"]'])
await expect(page.getByText('serialBRM02222869')).toBeVisible()
await expect(page.getByText('slot14')).toBeVisible()

const instancesTab = page.getByRole('tab', { name: 'Instances' })
await expect(instancesTab).toBeVisible()
Expand Down
Loading