Tighten TrueNAS Storage page to peer pattern

Bring TrueNAS Storage table in line with Kubernetes/Docker/Proxmox
peers on the canonical platform primitives.

- Add coloured leading dots to Healthy/Attention/Offline chips so the
  filter toolbar matches PLATFORM_HEALTH_FILTER_OPTIONS.
- Drop the redundant State column. Health was being signalled three
  times (row status dot, raw ZFS/SMART text, Health pill); raw state
  still surfaces in the resource drawer.
- Drop the Shares column, which printed 0 on nearly every row; share
  count remains available in the dataset detail.
- Rename TableCardHeader title to "Storage" to match peer titles
  ("Nodes", "Services", "Deployments").
This commit is contained in:
rcourtman
2026-05-23 21:39:34 +01:00
parent 2bec995c10
commit 5454f4e15b
@@ -22,6 +22,7 @@ import {
createPlatformTableFilterState,
getPlatformTableCellClassForKind,
getPlatformTableHeadClassForKind,
platformChipStatusDot,
type PlatformTableFilterOption,
} from '@/features/platformPage/sharedPlatformPage';
import {
@@ -42,9 +43,24 @@ import {
const TRUENAS_STORAGE_STATUS_OPTIONS: PlatformTableFilterOption<TrueNASStorageStatusFilter>[] = [
{ value: 'all', label: 'All' },
{ value: 'healthy', label: 'Healthy', tone: 'success' },
{ value: 'attention', label: 'Attention', tone: 'warning' },
{ value: 'offline', label: 'Offline', tone: 'danger' },
{
value: 'healthy',
label: 'Healthy',
tone: 'success',
leading: platformChipStatusDot('bg-emerald-500'),
},
{
value: 'attention',
label: 'Attention',
tone: 'warning',
leading: platformChipStatusDot('bg-amber-500'),
},
{
value: 'offline',
label: 'Offline',
tone: 'danger',
leading: platformChipStatusDot('bg-red-500'),
},
];
const titleCase = (value: string | undefined): string => {
@@ -62,22 +78,6 @@ const kindLabel = (kind: TrueNASStorageTopologyKind): string => {
return 'Disk';
};
const stateLabel = (row: TrueNASStorageTopologyRow): string => {
if (row.kind === 'pool') {
return (
asTrimmedString(row.resource.storage?.zfsPoolState)?.toUpperCase() ||
titleCase(row.resource.status)
);
}
if (row.kind === 'disk') {
return (
asTrimmedString(row.resource.physicalDisk?.health)?.toUpperCase() ||
titleCase(row.resource.status)
);
}
return titleCase(row.resource.status);
};
const subtitle = (row: TrueNASStorageTopologyRow): string => {
if (row.kind === 'pool') return row.resource.parentName || 'TrueNAS pool';
if (row.kind === 'dataset') return row.resource.parentName || 'Dataset';
@@ -179,11 +179,6 @@ const diskCountLabel = (row: TrueNASStorageTopologyRow): string => {
return '-';
};
const shareCountLabel = (row: TrueNASStorageTopologyRow): string => {
if (row.kind === 'disk') return '-';
return String(row.counts.shares);
};
export const getTrueNASStorageTopologyIndentClass = (depth: number): string => {
if (depth <= 0) return '';
if (depth === 1) return 'pl-5 sm:pl-7';
@@ -268,40 +263,30 @@ export const TrueNASStorageTopologyTable: Component<{
}
>
<TableCard class={PLATFORM_TABLE_CARD_CLASS}>
<TableCardHeader title="Storage Topology" />
<TableCardHeader title="Storage" />
<Table class="min-w-full table-fixed text-xs md:min-w-[960px]">
<TableHeader>
<TableRow class={PLATFORM_TABLE_HEADER_ROW_CLASS}>
<TableHead class={`${getPlatformTableHeadClassForKind('name')} md:w-[27%]`}>
<TableHead class={`${getPlatformTableHeadClassForKind('name')} md:w-[32%]`}>
Resource
</TableHead>
<TableHead class={`${getPlatformTableHeadClassForKind('text')} md:w-[9%]`}>
<TableHead class={`${getPlatformTableHeadClassForKind('text')} md:w-[10%]`}>
Kind
</TableHead>
<TableHead
class={`${getPlatformTableHeadClassForKind('text')} hidden sm:table-cell md:w-[10%]`}
>
State
</TableHead>
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} md:w-[22%]`}>
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} md:w-[28%]`}>
Usage / Size
</TableHead>
<TableHead
class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[8%]`}
>
Shares
</TableHead>
<TableHead
class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[8%]`}
>
Disks
</TableHead>
<TableHead
class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden lg:table-cell md:w-[6%]`}
class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden lg:table-cell md:w-[8%]`}
>
Temp
</TableHead>
<TableHead class={`${getPlatformTableHeadClassForKind('badge')} md:w-[10%]`}>
<TableHead class={`${getPlatformTableHeadClassForKind('badge')} md:w-[14%]`}>
Health
</TableHead>
</TableRow>
@@ -332,19 +317,9 @@ export const TrueNASStorageTopologyTable: Component<{
<TableCell class={getPlatformTableCellClassForKind('text')}>
<span class="text-base-content">{kindLabel(row.kind)}</span>
</TableCell>
<TableCell
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content sm:table-cell`}
>
<span class="font-mono text-[11px]">{stateLabel(row)}</span>
</TableCell>
<TableCell class={getPlatformTableCellClassForKind('metric-bar')}>
<CapacityCell row={row} />
</TableCell>
<TableCell
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content tabular-nums md:table-cell`}
>
{shareCountLabel(row)}
</TableCell>
<TableCell
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content tabular-nums md:table-cell`}
>
@@ -363,7 +338,7 @@ export const TrueNASStorageTopologyTable: Component<{
resource={resource()}
open={isExpanded()}
detailRowId={detailRowId()}
colSpan={8}
colSpan={6}
resolveResourceLabel={resolveResourceLabel}
onClose={() => drawer.close(resource())}
/>