Skip to content

Commit

Permalink
use beautiful column grouping
Browse files Browse the repository at this point in the history
  • Loading branch information
david-crespo committed Dec 18, 2024
1 parent 1b44e4c commit 9758a93
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 39 deletions.
4 changes: 2 additions & 2 deletions app/pages/system/UtilizationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ function UsageTab() {
<Table className="w-full">
<Table.Header>
<Table.HeaderRow>
<Table.HeadCell>Silo</Table.HeadCell>
<Table.HeadCell data-test-ignore></Table.HeadCell>
{/* data-test-ignore makes the row asserts work in the e2e tests */}
<Table.HeadCell colSpan={3} data-test-ignore>
Provisioned / Quota
Expand All @@ -173,7 +173,7 @@ function UsageTab() {
<Table.HeadCell data-test-ignore></Table.HeadCell>
</Table.HeaderRow>
<Table.HeaderRow>
<Table.HeadCell data-test-ignore></Table.HeadCell>
<Table.HeadCell>Silo</Table.HeadCell>
<Table.HeadCell>CPU</Table.HeadCell>
<Table.HeadCell>Memory</Table.HeadCell>
<Table.HeadCell>Storage</Table.HeadCell>
Expand Down
70 changes: 45 additions & 25 deletions app/pages/system/inventory/SledsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,21 @@ import {
getListQFn,
queryClient,
type Sled,
type SledProvisionPolicy,
type SledPolicy,
type SledState,
} from '@oxide/api'
import { Servers24Icon } from '@oxide/design-system/icons/react'
import {
Checkmark12Icon,
Close12Icon,
Servers24Icon,
} from '@oxide/design-system/icons/react'

import { makeLinkCell } from '~/table/cells/LinkCell'
import { useQueryTable } from '~/table/QueryTable'
import { Badge, type BadgeColor } from '~/ui/lib/Badge'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
import { pb } from '~/util/path-builder'

const PROV_POLICY_DISP: Record<SledProvisionPolicy, [string, BadgeColor]> = {
provisionable: ['Provisionable', 'default'],
non_provisionable: ['Not provisionable', 'neutral'],
}

const STATE_BADGE_COLORS: Record<SledState, BadgeColor> = {
active: 'default',
decommissioned: 'neutral',
Expand All @@ -45,24 +44,45 @@ const staticCols = [
cell: makeLinkCell((sledId) => pb.sled({ sledId })),
}),
// TODO: colHelper.accessor('baseboard.serviceAddress', { header: 'service address' }),
colHelper.accessor('baseboard.part', { header: 'part number' }),
colHelper.accessor('baseboard.serial', { header: 'serial number' }),
colHelper.accessor('baseboard.revision', { header: 'revision' }),
colHelper.accessor('policy', {
header: 'policy',
cell: (info) => {
const policy = info.getValue()
if (policy.kind === 'expunged') return <Badge color="neutral">Expunged</Badge>
const [label, color] = PROV_POLICY_DISP[policy.provisionPolicy]
return (
<div className="space-x-0.5">
<Badge>In service</Badge>
<Badge variant="solid" color={color}>
{label}
</Badge>
</div>
)
},
colHelper.group({
id: 'baseboard',
header: 'Baseboard',
columns: [
colHelper.accessor('baseboard.part', { header: 'part number' }),
colHelper.accessor('baseboard.serial', { header: 'serial number' }),
colHelper.accessor('baseboard.revision', { header: 'revision' }),
],
}),
colHelper.group({
id: 'policy',
header: 'Policy',
columns: [
colHelper.accessor('policy', {
header: 'Kind',
cell: (info) => {
// need to cast because inference is broken inside groups
// https://github.com/TanStack/table/issues/5065
const policy: SledPolicy = info.getValue()
return policy.kind === 'expunged' ? (
<Badge color="neutral">Expunged</Badge>
) : (
<Badge>In service</Badge>
)
},
}),
colHelper.accessor('policy', {
header: 'Provisionable',
cell: (info) => {
const policy: SledPolicy = info.getValue()
if (policy.kind === 'expunged') return <Close12Icon />
return policy.provisionPolicy === 'provisionable' ? (
<Checkmark12Icon className="text-accent" />
) : (
<Close12Icon />
)
},
}),
],
}),
colHelper.accessor('state', {
cell: (info) => (
Expand Down
36 changes: 24 additions & 12 deletions app/table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,30 @@ export const Table = <TData,>({
}: TableProps<TData>) => (
<UITable {...tableProps}>
<UITable.Header>
{table.getHeaderGroups().map((headerGroup) => (
<UITable.HeaderRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<UITable.HeadCell
key={header.id}
className={header.column.columnDef.meta?.thClassName}
>
{flexRender(header.column.columnDef.header, header.getContext())}
</UITable.HeadCell>
))}
</UITable.HeaderRow>
))}
{table.getHeaderGroups().map((headerGroup) => {
console.log(headerGroup)
return (
<UITable.HeaderRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<UITable.HeadCell
key={header.id}
className={header.column.columnDef.meta?.thClassName}
colSpan={header.colSpan}
>
{
// Placeholder concept is for when grouped columns are
// combined with regular columns. The regular column only
// needs one entry in the stack of header cells, so the others
// have isPlacholder=true. See sleds table for an example.
header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())
}
</UITable.HeadCell>
))}
</UITable.HeaderRow>
)
})}
</UITable.Header>
<UITable.Body>
{table.getRowModel().rows.map((row) => {
Expand Down

0 comments on commit 9758a93

Please sign in to comment.