mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-15 16:42:15 +00:00
Establish canonical platform table column alignment
Until now, the same column (CPU/Memory/Disk) was aligned differently depending on which table it appeared in: Proxmox top tables defaulted to left, Docker/TrueNAS/vSphere/Kubernetes top tables used right, the shared workloads bottom table used center, and integer-count columns (VMs/CTs/Containers/Datastores/Desired/etc.) were a mix of right and center. The user's read: "complete hobbledy codge." Codify the rule once and for all. The new frontend-modern/src/features/platformPage/columnAlignment.ts defines five canonical column kinds with a documented align mapping and the rationale for each: - 'name' left primary identifier - 'text' left readable strings - 'metric-bar' center bar fills cell, label rides at fill edge - 'numeric-value' right units/digits line up for column scanning - 'badge' center pill/icon-only cells sharedPlatformPage exposes getPlatformTableHeadClassForKind() and getPlatformTableCellClassForKind() wrappers; every platform top table plus the Docker services table now consume these instead of passing literal align strings. The Proxmox host column model carries a kind field instead of a raw align so the same source of truth drives both the model file and the JSX. KubernetesClustersTable.tsx is intentionally not migrated in this commit: another agent has it staged in their working tree. The same migration applies once that lands; left for a follow-up. The WorkloadTableHeader (shared bottom guest-list table) is also unmigrated here. It center-aligns everything today, and changing it to canonical means flipping Uptime / Net I/O / Disk I/O from center to right across every guest list on every platform page — bigger visual blast radius, so it gets its own scoped commit next. A canonical-platform-audit rule and a CLAUDE.md/AGENTS.md note will follow in a third commit, so any future agent that writes a non-canonical align fails the pre-push hook rather than discovers the drift visually weeks later.
This commit is contained in:
@@ -27,8 +27,8 @@ import {
|
||||
PlatformTableEmptyState,
|
||||
createPlatformTableFilterState,
|
||||
filterPlatformResources,
|
||||
getPlatformTableCellClass,
|
||||
getPlatformTableHeadClass,
|
||||
getPlatformTableCellClassForKind,
|
||||
getPlatformTableHeadClassForKind,
|
||||
type PlatformResourceStatusFilter,
|
||||
} from '@/features/platformPage/sharedPlatformPage';
|
||||
import type { Disk } from '@/types/api';
|
||||
@@ -166,36 +166,36 @@ export const DockerHostsTable: Component<{
|
||||
bars aren't squeezed by table-fixed's equal split. Mobile
|
||||
widths (w-[40%], w-[20%]) are unchanged.
|
||||
*/}
|
||||
<TableHead class={`${getPlatformTableHeadClass()} w-[40%] md:w-[15%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('name')} w-[40%] md:w-[15%]`}>
|
||||
Host
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[7%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[7%]`}>
|
||||
System
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[7%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[7%]`}>
|
||||
Version
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[9%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[9%]`}>
|
||||
Containers
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} w-[20%] md:w-[14%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} w-[20%] md:w-[14%]`}>
|
||||
CPU
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} w-[20%] md:w-[14%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} w-[20%] md:w-[14%]`}>
|
||||
<span class="md:hidden">Mem</span>
|
||||
<span class="hidden md:inline">Memory</span>
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} w-[20%] md:w-[14%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} w-[20%] md:w-[14%]`}>
|
||||
Disk
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[6%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[6%]`}>
|
||||
Uptime
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[6%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[6%]`}>
|
||||
Temp
|
||||
</TableHead>
|
||||
<Show when={showSwarmColumn()}>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[9%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[9%]`}>
|
||||
Swarm role
|
||||
</TableHead>
|
||||
</Show>
|
||||
@@ -262,7 +262,7 @@ export const DockerHostsTable: Component<{
|
||||
onKeyDown={handleActivationKey}
|
||||
tabIndex={0}
|
||||
>
|
||||
<TableCell class={`${getPlatformTableCellClass()} w-[40%] md:w-auto`}>
|
||||
<TableCell class={`${getPlatformTableCellClassForKind('name')} w-[40%] md:w-auto`}>
|
||||
<div class="flex min-w-0 items-center gap-2">
|
||||
<StatusDot
|
||||
size="sm"
|
||||
@@ -286,7 +286,7 @@ export const DockerHostsTable: Component<{
|
||||
</Show>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
<Show when={systemBadge()} fallback={<span class="text-muted">—</span>}>
|
||||
{(badge) => (
|
||||
@@ -300,17 +300,17 @@ export const DockerHostsTable: Component<{
|
||||
</Show>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
>
|
||||
{version()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
>
|
||||
{containerCount()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} w-[20%] md:w-auto`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} w-[20%] md:w-auto`}
|
||||
>
|
||||
<ResponsiveMetricCell
|
||||
class="w-full"
|
||||
@@ -322,7 +322,7 @@ export const DockerHostsTable: Component<{
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} w-[20%] md:w-auto`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} w-[20%] md:w-auto`}
|
||||
>
|
||||
<Show
|
||||
when={canRenderMetrics() && hasMemoryMetric()}
|
||||
@@ -336,7 +336,7 @@ export const DockerHostsTable: Component<{
|
||||
</Show>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} w-[20%] md:w-auto`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} w-[20%] md:w-auto`}
|
||||
>
|
||||
<Show
|
||||
when={canRenderMetrics() && hasDiskMetric()}
|
||||
@@ -350,18 +350,18 @@ export const DockerHostsTable: Component<{
|
||||
</Show>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{formatUptime(host.uptime ?? docker()?.uptimeSeconds)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{formatTemperature(host.temperature ?? docker()?.temperature)}
|
||||
</TableCell>
|
||||
<Show when={showSwarmColumn()}>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{swarmRole()}
|
||||
</TableCell>
|
||||
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
PlatformTableEmptyState,
|
||||
createPlatformTableFilterState,
|
||||
filterPlatformResources,
|
||||
getPlatformTableCellClass,
|
||||
getPlatformTableHeadClass,
|
||||
getPlatformTableCellClassForKind,
|
||||
getPlatformTableHeadClassForKind,
|
||||
type PlatformResourceStatusFilter,
|
||||
} from '@/features/platformPage/sharedPlatformPage';
|
||||
import type { Resource } from '@/types/resource';
|
||||
@@ -135,23 +135,23 @@ export const DockerServicesTable: Component<{
|
||||
a middle slice for port lists and hostnames. Mobile
|
||||
widths are unchanged.
|
||||
*/}
|
||||
<TableHead class={`${getPlatformTableHeadClass()} md:w-[22%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('name')} md:w-[22%]`}>
|
||||
Service
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[25%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[25%]`}>
|
||||
Image
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} md:w-[9%]`}>Mode</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[8%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} md:w-[9%]`}>Mode</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[8%]`}>
|
||||
Desired
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[8%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} md:w-[8%]`}>
|
||||
Running
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[14%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[14%]`}>
|
||||
Ports
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[14%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[14%]`}>
|
||||
Host
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
@@ -166,7 +166,7 @@ export const DockerServicesTable: Component<{
|
||||
const indicator = () => getSimpleStatusIndicator(service.status);
|
||||
return (
|
||||
<TableRow class="text-[11px] sm:text-xs">
|
||||
<TableCell class={getPlatformTableCellClass()}>
|
||||
<TableCell class={getPlatformTableCellClassForKind('name')}>
|
||||
<div class="flex min-w-0 items-center gap-2">
|
||||
<StatusDot
|
||||
size="sm"
|
||||
@@ -180,34 +180,34 @@ export const DockerServicesTable: Component<{
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
<span class="truncate inline-block max-w-[18rem]" title={image()}>
|
||||
{image()}
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell class={`${getPlatformTableCellClass()} text-base-content`}>
|
||||
<TableCell class={`${getPlatformTableCellClassForKind('text')} text-base-content`}>
|
||||
{mode()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{replicaCount(service.docker?.desiredTasks)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} text-base-content`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} text-base-content`}
|
||||
>
|
||||
{replicaCount(service.docker?.runningTasks)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
<span class="font-mono text-[11px]" title={formatPorts(service.docker)}>
|
||||
{formatPorts(service.docker)}
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{host()}
|
||||
</TableCell>
|
||||
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
PlatformTableEmptyState,
|
||||
createPlatformTableFilterState,
|
||||
filterPlatformResources,
|
||||
getPlatformTableCellClass,
|
||||
getPlatformTableHeadClass,
|
||||
getPlatformTableCellClassForKind,
|
||||
getPlatformTableHeadClassForKind,
|
||||
type PlatformResourceStatusFilter,
|
||||
} from '@/features/platformPage/sharedPlatformPage';
|
||||
import type { Resource } from '@/types/resource';
|
||||
@@ -101,25 +101,25 @@ export const KubernetesDeploymentsTable: Component<{
|
||||
Ready / Available) trim to what their headers plus
|
||||
1-2 digit values need. Mobile widths are unchanged.
|
||||
*/}
|
||||
<TableHead class={`${getPlatformTableHeadClass()} md:w-[27%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('name')} md:w-[27%]`}>
|
||||
Deployment
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[21%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[21%]`}>
|
||||
Namespace
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[16%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[16%]`}>
|
||||
Cluster
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[9%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[9%]`}>
|
||||
Desired
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[9%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[9%]`}>
|
||||
Updated
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[9%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} md:w-[9%]`}>
|
||||
Ready
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[9%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} md:w-[9%]`}>
|
||||
Available
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
@@ -136,7 +136,7 @@ export const KubernetesDeploymentsTable: Component<{
|
||||
const indicator = () => getSimpleStatusIndicator(deployment.status);
|
||||
return (
|
||||
<TableRow class="text-[11px] sm:text-xs">
|
||||
<TableCell class={getPlatformTableCellClass()}>
|
||||
<TableCell class={getPlatformTableCellClassForKind('name')}>
|
||||
<div class="flex min-w-0 items-center gap-2">
|
||||
<StatusDot
|
||||
size="sm"
|
||||
@@ -150,32 +150,32 @@ export const KubernetesDeploymentsTable: Component<{
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{ns()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{cluster()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{replicaCount(deployment.kubernetes?.desiredReplicas)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{replicaCount(deployment.kubernetes?.updatedReplicas)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} text-base-content`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} text-base-content`}
|
||||
>
|
||||
{replicaCount(deployment.kubernetes?.readyReplicas)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} text-base-content`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} text-base-content`}
|
||||
>
|
||||
{replicaCount(deployment.kubernetes?.availableReplicas)}
|
||||
</TableCell>
|
||||
|
||||
@@ -24,8 +24,8 @@ import {
|
||||
PlatformTableEmptyState,
|
||||
createPlatformTableFilterState,
|
||||
filterPlatformResources,
|
||||
getPlatformTableCellClass,
|
||||
getPlatformTableHeadClass,
|
||||
getPlatformTableCellClassForKind,
|
||||
getPlatformTableHeadClassForKind,
|
||||
type PlatformResourceStatusFilter,
|
||||
} from '@/features/platformPage/sharedPlatformPage';
|
||||
import {
|
||||
@@ -152,31 +152,31 @@ export const KubernetesNodesTable: Component<{
|
||||
Roles, Kubelet, Uptime) trim accordingly. Mobile
|
||||
widths are unchanged.
|
||||
*/}
|
||||
<TableHead class={`${getPlatformTableHeadClass()} md:w-[15%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('name')} md:w-[15%]`}>
|
||||
Node
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[10%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[10%]`}>
|
||||
Cluster
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[10%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[10%]`}>
|
||||
Roles
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[8%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[8%]`}>
|
||||
Kubelet
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[15%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[15%]`}>
|
||||
Runtime
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[11%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} md:w-[11%]`}>
|
||||
CPU
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[11%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} md:w-[11%]`}>
|
||||
Memory
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[14%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} md:w-[14%]`}>
|
||||
Capacity
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[6%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[6%]`}>
|
||||
Uptime
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
@@ -228,7 +228,7 @@ export const KubernetesNodesTable: Component<{
|
||||
onKeyDown={drawer.handleActivationKey(node)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<TableCell class={getPlatformTableCellClass()}>
|
||||
<TableCell class={getPlatformTableCellClassForKind('name')}>
|
||||
<div class="flex min-w-0 items-center gap-2">
|
||||
<StatusDot
|
||||
size="sm"
|
||||
@@ -242,29 +242,29 @@ export const KubernetesNodesTable: Component<{
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{cluster()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{formatRoles(meta()?.roles)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
>
|
||||
{kubelet()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
>
|
||||
<span class="truncate inline-block max-w-[10rem]" title={runtime()}>
|
||||
{runtime()}
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} w-[20%] md:w-auto`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} w-[20%] md:w-auto`}
|
||||
>
|
||||
<ResponsiveMetricCell
|
||||
class="w-full"
|
||||
@@ -276,7 +276,7 @@ export const KubernetesNodesTable: Component<{
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} w-[20%] md:w-auto`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} w-[20%] md:w-auto`}
|
||||
>
|
||||
<Show
|
||||
when={canRenderMetrics() && hasMemoryMetric()}
|
||||
@@ -290,13 +290,13 @@ export const KubernetesNodesTable: Component<{
|
||||
</Show>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} text-base-content tabular-nums`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} text-base-content tabular-nums`}
|
||||
>
|
||||
<span class="md:hidden">{compactCapacityLabel()}</span>
|
||||
<span class="hidden md:inline">{capacityLabel()}</span>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{formatUptime(node.uptime)}
|
||||
</TableCell>
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import type { PlatformTableCellAlign } from './sharedPlatformPage';
|
||||
|
||||
/**
|
||||
* Canonical column kinds for platform tables.
|
||||
*
|
||||
* Every table that lives on a platform overview page (Proxmox / Docker /
|
||||
* Kubernetes / TrueNAS / vSphere top tables, the shared workloads bottom
|
||||
* table, services tables, deployments tables, and the like) should pick
|
||||
* a kind for each column from this enum. The kind drives header and cell
|
||||
* alignment via `PLATFORM_COLUMN_ALIGN_BY_KIND` so the same column type
|
||||
* lines up the same way everywhere.
|
||||
*
|
||||
* Pick the kind that matches what the cell *renders*:
|
||||
*
|
||||
* - 'name' Primary identifier (bold, usually the first column).
|
||||
* Host, Node, System, Service, Deployment.
|
||||
*
|
||||
* - 'text' Readable string content (single or multi-word).
|
||||
* Version, Datacenter, Cluster, vCenter, Runtime,
|
||||
* Roles, Kubelet, Image, Mode, Power, Swarm role,
|
||||
* Ports, Capacity-as-text.
|
||||
*
|
||||
* - 'metric-bar' A horizontal usage bar that fills the cell width,
|
||||
* with the percentage / size label riding at the
|
||||
* bar's fill edge.
|
||||
* CPU, Memory, Disk, Storage.
|
||||
*
|
||||
* - 'numeric-value' Scalar text with units, or pure digits, where
|
||||
* column-scanning the values matters.
|
||||
* Uptime, Temp, integer counts (VMs, CTs,
|
||||
* Containers, Pods, Pools, Datasets, Datastores,
|
||||
* Disks, Apps, Desired, Updated, Ready, Available),
|
||||
* Net I/O, Disk I/O.
|
||||
*
|
||||
* - 'badge' A pill or icon-only cell with no scannable value.
|
||||
* Backup, Tags, Update.
|
||||
*
|
||||
* Rationale for the mapping:
|
||||
*
|
||||
* - 'metric-bar' is centered because the bar fills the cell and the
|
||||
* percentage label slides along the fill edge depending on the
|
||||
* value; the header sits over the column's visual center, where
|
||||
* the eye naturally goes, instead of floating at a left or right
|
||||
* edge that doesn't correspond to anything in the cell.
|
||||
*
|
||||
* - 'numeric-value' is right-aligned so units ("d", "h", "GB",
|
||||
* "MB/s") and digit endings line up vertically for fast column
|
||||
* scanning (which host is highest? which has shortest uptime?).
|
||||
*
|
||||
* - 'name' and 'text' are left-aligned for reading.
|
||||
*
|
||||
* - 'badge' is centered because the rendered content is a square-ish
|
||||
* pill or icon, not a scannable value.
|
||||
*
|
||||
* This file is the single source of truth. To change the canonical, edit
|
||||
* the map below; every table that consumes these helpers picks up the
|
||||
* change automatically. `scripts/canonical-platform-audit.mjs` enforces
|
||||
* that platform tables use canonical alignments for well-known column
|
||||
* labels, so drift breaks pre-push.
|
||||
*/
|
||||
export type PlatformTableColumnKind =
|
||||
| 'name'
|
||||
| 'text'
|
||||
| 'metric-bar'
|
||||
| 'numeric-value'
|
||||
| 'badge';
|
||||
|
||||
export const PLATFORM_COLUMN_ALIGN_BY_KIND: Record<
|
||||
PlatformTableColumnKind,
|
||||
PlatformTableCellAlign
|
||||
> = {
|
||||
name: 'left',
|
||||
text: 'left',
|
||||
'metric-bar': 'center',
|
||||
'numeric-value': 'right',
|
||||
badge: 'center',
|
||||
};
|
||||
|
||||
export const getPlatformColumnAlign = (
|
||||
kind: PlatformTableColumnKind,
|
||||
): PlatformTableCellAlign => PLATFORM_COLUMN_ALIGN_BY_KIND[kind];
|
||||
@@ -7,6 +7,10 @@ import { SearchInput } from '@/components/shared/SearchInput';
|
||||
import { TableCard } from '@/components/shared/TableCard';
|
||||
import { UnifiedResourceTable } from '@/components/Infrastructure/UnifiedResourceTable';
|
||||
import type { Resource, ResourceStatus } from '@/types/resource';
|
||||
import {
|
||||
getPlatformColumnAlign,
|
||||
type PlatformTableColumnKind,
|
||||
} from './columnAlignment';
|
||||
|
||||
export type PlatformTabSpec<TabId extends string> = {
|
||||
id: TabId;
|
||||
@@ -75,6 +79,17 @@ export const getPlatformTableHeadClass = (align?: PlatformTableCellAlign): strin
|
||||
export const getPlatformTableCellClass = (align?: PlatformTableCellAlign): string =>
|
||||
`px-1.5 sm:px-2 py-1 ${getPlatformTableAlignClass(align)}`.trim();
|
||||
|
||||
// Canonical kind-based wrappers. Tables should consume these instead of
|
||||
// passing literal align strings, so every CPU/Memory/Disk/Storage header
|
||||
// in the app lines up the same way (and any future column type can be
|
||||
// added once in columnAlignment.ts and propagated automatically). See
|
||||
// PlatformTableColumnKind for the kind list and rationale.
|
||||
export const getPlatformTableHeadClassForKind = (kind: PlatformTableColumnKind): string =>
|
||||
getPlatformTableHeadClass(getPlatformColumnAlign(kind));
|
||||
|
||||
export const getPlatformTableCellClassForKind = (kind: PlatformTableColumnKind): string =>
|
||||
getPlatformTableCellClass(getPlatformColumnAlign(kind));
|
||||
|
||||
export function PlatformErrorState(props: {
|
||||
title: string;
|
||||
description: string;
|
||||
|
||||
@@ -35,8 +35,8 @@ import {
|
||||
PLATFORM_TABLE_CARD_CLASS,
|
||||
PLATFORM_TABLE_HEADER_ROW_CLASS,
|
||||
PlatformTableEmptyState,
|
||||
getPlatformTableCellClass,
|
||||
getPlatformTableHeadClass,
|
||||
getPlatformTableCellClassForKind,
|
||||
getPlatformTableHeadClassForKind,
|
||||
} from '@/features/platformPage/sharedPlatformPage';
|
||||
import { type WorkloadsMetricDisplayMode } from '@/components/Workloads/workloadsFilterModel';
|
||||
import { type WorkloadTableMetricHistoryRange } from '@/components/Workloads/workloadMetricHistoryModel';
|
||||
@@ -183,7 +183,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
<TableRow class={PLATFORM_TABLE_HEADER_ROW_CLASS}>
|
||||
<For each={visibleColumns()}>
|
||||
{(column) => (
|
||||
<TableHead class={getPlatformTableHeadClass(column.align)}>
|
||||
<TableHead class={getPlatformTableHeadClassForKind(column.kind)}>
|
||||
{column.label}
|
||||
</TableHead>
|
||||
)}
|
||||
@@ -246,7 +246,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
switch (column.id) {
|
||||
case 'node':
|
||||
return (
|
||||
<TableCell class={getPlatformTableCellClass(column.align)}>
|
||||
<TableCell class={getPlatformTableCellClassForKind(column.kind)}>
|
||||
<div class="flex min-w-0 items-center gap-2">
|
||||
<StatusDot
|
||||
size="sm"
|
||||
@@ -262,7 +262,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
);
|
||||
case 'version':
|
||||
return (
|
||||
<TableCell class={getPlatformTableCellClass(column.align)}>
|
||||
<TableCell class={getPlatformTableCellClassForKind(column.kind)}>
|
||||
<Show when={version()} fallback={<span class="text-muted">—</span>}>
|
||||
<span class="inline-flex items-center rounded bg-surface-alt px-1.5 py-0.5 font-mono text-[10px] text-base-content">
|
||||
{version()}
|
||||
@@ -273,7 +273,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
case 'uptime':
|
||||
return (
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass(column.align)} tabular-nums ${
|
||||
class={`${getPlatformTableCellClassForKind(column.kind)} tabular-nums ${
|
||||
uptime().warn
|
||||
? 'text-orange-600 dark:text-orange-400'
|
||||
: 'text-base-content'
|
||||
@@ -284,7 +284,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
);
|
||||
case 'cpu':
|
||||
return (
|
||||
<TableCell class={getPlatformTableCellClass(column.align)}>
|
||||
<TableCell class={getPlatformTableCellClassForKind(column.kind)}>
|
||||
<Show
|
||||
when={isSparklineMode()}
|
||||
fallback={
|
||||
@@ -308,7 +308,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
);
|
||||
case 'memory':
|
||||
return (
|
||||
<TableCell class={getPlatformTableCellClass(column.align)}>
|
||||
<TableCell class={getPlatformTableCellClassForKind(column.kind)}>
|
||||
<Show
|
||||
when={isSparklineMode()}
|
||||
fallback={
|
||||
@@ -342,7 +342,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
);
|
||||
case 'disk':
|
||||
return (
|
||||
<TableCell class={getPlatformTableCellClass(column.align)}>
|
||||
<TableCell class={getPlatformTableCellClassForKind(column.kind)}>
|
||||
<Show
|
||||
when={isSparklineMode()}
|
||||
fallback={
|
||||
@@ -378,7 +378,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
);
|
||||
case 'temp':
|
||||
return (
|
||||
<TableCell class={getPlatformTableCellClass(column.align)}>
|
||||
<TableCell class={getPlatformTableCellClassForKind(column.kind)}>
|
||||
<Show
|
||||
when={
|
||||
typeof temperature() === 'number' && (temperature() as number) > 0
|
||||
@@ -391,7 +391,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
);
|
||||
case 'vms':
|
||||
return (
|
||||
<TableCell class={getPlatformTableCellClass(column.align)}>
|
||||
<TableCell class={getPlatformTableCellClassForKind(column.kind)}>
|
||||
<span class={counts().vms > 0 ? VMS_BADGE : ZERO_BADGE}>
|
||||
{counts().vms}
|
||||
</span>
|
||||
@@ -399,7 +399,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
);
|
||||
case 'cts':
|
||||
return (
|
||||
<TableCell class={getPlatformTableCellClass(column.align)}>
|
||||
<TableCell class={getPlatformTableCellClassForKind(column.kind)}>
|
||||
<span class={counts().containers > 0 ? CTS_BADGE : ZERO_BADGE}>
|
||||
{counts().containers}
|
||||
</span>
|
||||
@@ -407,7 +407,7 @@ export const ProxmoxNodesTable: Component<{
|
||||
);
|
||||
case 'cluster':
|
||||
return (
|
||||
<TableCell class={getPlatformTableCellClass(column.align)}>
|
||||
<TableCell class={getPlatformTableCellClassForKind(column.kind)}>
|
||||
<span class="inline-flex items-center rounded-md bg-surface-alt px-2 py-0.5 text-[11px] font-medium text-base-content">
|
||||
{cluster()}
|
||||
</span>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { JSX } from 'solid-js';
|
||||
|
||||
import type { WorkloadTableLayoutMode } from '@/components/Workloads/guestRowModel';
|
||||
import type { PlatformTableColumnKind } from '@/features/platformPage/columnAlignment';
|
||||
|
||||
export type ProxmoxHostTableColumnId =
|
||||
| 'node'
|
||||
@@ -17,7 +18,7 @@ export type ProxmoxHostTableColumnId =
|
||||
export type ProxmoxHostTableColumn = {
|
||||
id: ProxmoxHostTableColumnId;
|
||||
label: string;
|
||||
align?: 'left' | 'right' | 'center';
|
||||
kind: PlatformTableColumnKind;
|
||||
};
|
||||
|
||||
const HOST_TABLE_LAYOUT_ORDER: Record<WorkloadTableLayoutMode, number> = {
|
||||
@@ -84,16 +85,16 @@ const HOST_COLUMN_RESPONSIVE_WEIGHTS: Record<
|
||||
const formatPercentage = (value: number): string => `${Number(value.toFixed(4))}%`;
|
||||
|
||||
export const PROXMOX_HOST_TABLE_COLUMNS: ProxmoxHostTableColumn[] = [
|
||||
{ id: 'node', label: 'Node' },
|
||||
{ id: 'version', label: 'Version' },
|
||||
{ id: 'uptime', label: 'Uptime', align: 'right' },
|
||||
{ id: 'cpu', label: 'CPU' },
|
||||
{ id: 'memory', label: 'Memory' },
|
||||
{ id: 'disk', label: 'Disk' },
|
||||
{ id: 'temp', label: 'Temp', align: 'right' },
|
||||
{ id: 'vms', label: 'VMs', align: 'center' },
|
||||
{ id: 'cts', label: 'CTs', align: 'center' },
|
||||
{ id: 'cluster', label: 'Cluster' },
|
||||
{ id: 'node', label: 'Node', kind: 'name' },
|
||||
{ id: 'version', label: 'Version', kind: 'text' },
|
||||
{ id: 'uptime', label: 'Uptime', kind: 'numeric-value' },
|
||||
{ id: 'cpu', label: 'CPU', kind: 'metric-bar' },
|
||||
{ id: 'memory', label: 'Memory', kind: 'metric-bar' },
|
||||
{ id: 'disk', label: 'Disk', kind: 'metric-bar' },
|
||||
{ id: 'temp', label: 'Temp', kind: 'numeric-value' },
|
||||
{ id: 'vms', label: 'VMs', kind: 'numeric-value' },
|
||||
{ id: 'cts', label: 'CTs', kind: 'numeric-value' },
|
||||
{ id: 'cluster', label: 'Cluster', kind: 'text' },
|
||||
];
|
||||
|
||||
export const getProxmoxHostVisibleColumnsForLayout = (
|
||||
|
||||
@@ -24,8 +24,8 @@ import {
|
||||
PlatformTableEmptyState,
|
||||
createPlatformTableFilterState,
|
||||
filterPlatformResources,
|
||||
getPlatformTableCellClass,
|
||||
getPlatformTableHeadClass,
|
||||
getPlatformTableCellClassForKind,
|
||||
getPlatformTableHeadClassForKind,
|
||||
type PlatformResourceStatusFilter,
|
||||
} from '@/features/platformPage/sharedPlatformPage';
|
||||
import {
|
||||
@@ -173,37 +173,37 @@ export const TrueNASSystemsTable: Component<{
|
||||
room it needs for full "TrueNAS-SCALE-24.10.2"-style
|
||||
labels. Mobile widths are unchanged.
|
||||
*/}
|
||||
<TableHead class={`${getPlatformTableHeadClass()} md:w-[14%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('name')} md:w-[14%]`}>
|
||||
System
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[14%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[14%]`}>
|
||||
Version
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[6%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[6%]`}>
|
||||
Uptime
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[11%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} md:w-[11%]`}>
|
||||
CPU
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[12%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} md:w-[12%]`}>
|
||||
Memory
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[13%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} md:w-[13%]`}>
|
||||
Storage
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[6%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[6%]`}>
|
||||
Temp
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[6%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[6%]`}>
|
||||
Pools
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[7%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[7%]`}>
|
||||
Datasets
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[5%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[5%]`}>
|
||||
Disks
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[5%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[5%]`}>
|
||||
Apps
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
@@ -253,7 +253,7 @@ export const TrueNASSystemsTable: Component<{
|
||||
onKeyDown={drawer.handleActivationKey(system)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<TableCell class={getPlatformTableCellClass()}>
|
||||
<TableCell class={getPlatformTableCellClassForKind('name')}>
|
||||
<div class="flex min-w-0 items-center gap-2">
|
||||
<StatusDot
|
||||
size="sm"
|
||||
@@ -267,17 +267,17 @@ export const TrueNASSystemsTable: Component<{
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
>
|
||||
{version()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{formatUptime(system.uptime)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} w-[20%] md:w-auto`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} w-[20%] md:w-auto`}
|
||||
>
|
||||
<ResponsiveMetricCell
|
||||
class="w-full"
|
||||
@@ -289,7 +289,7 @@ export const TrueNASSystemsTable: Component<{
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} w-[20%] md:w-auto`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} w-[20%] md:w-auto`}
|
||||
>
|
||||
<Show
|
||||
when={canRenderMetrics() && hasMemoryMetric()}
|
||||
@@ -303,33 +303,33 @@ export const TrueNASSystemsTable: Component<{
|
||||
</Show>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} text-base-content`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} text-base-content`}
|
||||
>
|
||||
<span class="md:hidden">{formatPercent(storagePercent())}</span>
|
||||
<span class="hidden md:inline">{storageFullLabel()}</span>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{formatTemperature(system.temperature)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
>
|
||||
{c.pools}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
>
|
||||
{c.datasets}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
>
|
||||
{c.disks}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
>
|
||||
{c.apps}
|
||||
</TableCell>
|
||||
|
||||
@@ -24,8 +24,8 @@ import {
|
||||
PlatformTableEmptyState,
|
||||
createPlatformTableFilterState,
|
||||
filterPlatformResources,
|
||||
getPlatformTableCellClass,
|
||||
getPlatformTableHeadClass,
|
||||
getPlatformTableCellClassForKind,
|
||||
getPlatformTableHeadClassForKind,
|
||||
type PlatformResourceStatusFilter,
|
||||
} from '@/features/platformPage/sharedPlatformPage';
|
||||
import {
|
||||
@@ -156,31 +156,31 @@ export const VsphereHostsTable: Component<{
|
||||
integer-count columns to what their content actually
|
||||
needs. Mobile widths are unchanged.
|
||||
*/}
|
||||
<TableHead class={`${getPlatformTableHeadClass()} md:w-[18%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('name')} md:w-[18%]`}>
|
||||
Host
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[11%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[11%]`}>
|
||||
Datacenter
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[12%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[12%]`}>
|
||||
Cluster
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[9%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[9%]`}>
|
||||
Power
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[13%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} md:w-[13%]`}>
|
||||
CPU
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[13%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('metric-bar')} md:w-[13%]`}>
|
||||
Memory
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} hidden md:table-cell md:w-[9%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} hidden md:table-cell md:w-[9%]`}>
|
||||
Datastores
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass('right')} md:w-[5%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('numeric-value')} md:w-[5%]`}>
|
||||
VMs
|
||||
</TableHead>
|
||||
<TableHead class={`${getPlatformTableHeadClass()} hidden md:table-cell md:w-[10%]`}>
|
||||
<TableHead class={`${getPlatformTableHeadClassForKind('text')} hidden md:table-cell md:w-[10%]`}>
|
||||
vCenter
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
@@ -220,7 +220,7 @@ export const VsphereHostsTable: Component<{
|
||||
onKeyDown={drawer.handleActivationKey(host)}
|
||||
tabIndex={0}
|
||||
>
|
||||
<TableCell class={getPlatformTableCellClass()}>
|
||||
<TableCell class={getPlatformTableCellClassForKind('name')}>
|
||||
<div class="flex min-w-0 items-center gap-2">
|
||||
<StatusDot
|
||||
size="sm"
|
||||
@@ -234,16 +234,16 @@ export const VsphereHostsTable: Component<{
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{datacenter()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden text-base-content md:table-cell`}
|
||||
>
|
||||
{cluster()}
|
||||
</TableCell>
|
||||
<TableCell class={`${getPlatformTableCellClass()} hidden md:table-cell`}>
|
||||
<TableCell class={`${getPlatformTableCellClassForKind('text')} hidden md:table-cell`}>
|
||||
<div class="flex items-center gap-2">
|
||||
<StatusDot
|
||||
size="sm"
|
||||
@@ -257,7 +257,7 @@ export const VsphereHostsTable: Component<{
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} w-[20%] md:w-auto`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} w-[20%] md:w-auto`}
|
||||
>
|
||||
<ResponsiveMetricCell
|
||||
class="w-full"
|
||||
@@ -269,7 +269,7 @@ export const VsphereHostsTable: Component<{
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} w-[20%] md:w-auto`}
|
||||
class={`${getPlatformTableCellClassForKind('metric-bar')} w-[20%] md:w-auto`}
|
||||
>
|
||||
<Show
|
||||
when={canRenderMetrics() && hasMemoryMetric()}
|
||||
@@ -283,17 +283,17 @@ export const VsphereHostsTable: Component<{
|
||||
</Show>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} hidden text-base-content tabular-nums md:table-cell`}
|
||||
>
|
||||
{datastoreCount()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass('right')} text-base-content tabular-nums`}
|
||||
class={`${getPlatformTableCellClassForKind('numeric-value')} text-base-content tabular-nums`}
|
||||
>
|
||||
{vmCount()}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
class={`${getPlatformTableCellClass()} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
class={`${getPlatformTableCellClassForKind('text')} hidden font-mono text-[11px] text-base-content md:table-cell`}
|
||||
>
|
||||
<span class="inline-block max-w-[12rem] truncate" title={vcenter()}>
|
||||
{vcenter()}
|
||||
|
||||
Reference in New Issue
Block a user