diff --git a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md
index f788f7d184..b09b3beb27 100644
--- a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md
+++ b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md
@@ -309,7 +309,10 @@ regression protection.
`WorkloadPanel` owns the mutually exclusive host/guest drawer handoff:
clicking a grouped host row while a guest drawer is open must clear the
selected guest and keep/focus the host summary group so the node drawer can
- replace the guest drawer.
+ replace the guest drawer. Platform pages that render a dedicated host
+ table above an embedded Workloads table may disable the grouped host drawer
+ through the explicit Workloads surface option, but standalone Workloads
+ must keep the inline grouped-row drawer as the default.
Compact icon headers inside `WorkloadTableHeader.tsx` may stay visually
dense for responsive workload tables, but the icon must be decorative and
the column label must remain present through an `sr-only` label so the
diff --git a/frontend-modern/src/components/Workloads/StackedDiskBar.tsx b/frontend-modern/src/components/Workloads/StackedDiskBar.tsx
index 47c8da8a7e..6793e18121 100644
--- a/frontend-modern/src/components/Workloads/StackedDiskBar.tsx
+++ b/frontend-modern/src/components/Workloads/StackedDiskBar.tsx
@@ -14,6 +14,7 @@ export function StackedDiskBar(props: StackedDiskBarProps) {
if (!Number.isFinite(parsed)) return '0';
return String(Math.max(0, Math.min(parsed, 100)));
};
+ const invertPercent = (value: number) => String(100 - Math.max(0, Math.min(value, 100)));
return (
@@ -204,9 +205,25 @@ export function StackedDiskBar(props: StackedDiskBarProps) {
>
+ class="absolute inset-0 rounded-sm brightness-100 transition-[filter] duration-100 group-hover/disk:brightness-125"
+ >
+
+
+
+
)}
diff --git a/frontend-modern/src/components/Workloads/WorkloadPanel.tsx b/frontend-modern/src/components/Workloads/WorkloadPanel.tsx
index 498e795167..3e19453f3f 100644
--- a/frontend-modern/src/components/Workloads/WorkloadPanel.tsx
+++ b/frontend-modern/src/components/Workloads/WorkloadPanel.tsx
@@ -43,6 +43,7 @@ type WorkloadPanelProps = Pick<
| 'groupedWindowing'
| 'guestMetadata'
| 'guestParentNodeMap'
+ | 'groupNodeDrawerMode'
| 'groupingMode'
| 'handleCustomUrlUpdate'
| 'handleTagClick'
@@ -380,14 +381,17 @@ export function WorkloadPanel(props: WorkloadPanelProps) {
);
const shouldShowNodeDrawer = createMemo(
() =>
+ props.groupNodeDrawerMode() === 'inline' &&
Boolean(node()) &&
props.focusedSummaryWorkloadGroupId() === groupKey() &&
props.selectedGuestId() === null,
);
+ const canOpenNodeDrawer = () => props.groupNodeDrawerMode() === 'inline';
const handleGroupHoverChange = (next: SummarySeriesGroupScope | null) => {
props.setHoveredWorkloadGroupScope(next);
};
const handleGroupFocusToggle = () => {
+ if (!canOpenNodeDrawer()) return;
const scope = groupSummaryScope();
const selectedGuestId = props.selectedGuestId();
const nextFocusedScope =
@@ -445,7 +449,9 @@ export function WorkloadPanel(props: WorkloadPanelProps) {
node={node()!}
renderAs="tr"
colspan={props.totalColumns()}
- columns={props.compactGroupHeaders() ? undefined : props.workloadTableVisibleColumns()}
+ columns={
+ props.compactGroupHeaders() ? undefined : props.workloadTableVisibleColumns()
+ }
columnCellClass={
props.compactGroupHeaders() ? undefined : getGroupNodeColumnCellClass
}
@@ -456,15 +462,23 @@ export function WorkloadPanel(props: WorkloadPanelProps) {
!props.compactGroupHeaders() &&
!props.workloadTableVisibleColumnIds().includes('info')
}
- trClass="cursor-pointer select-none duration-150"
+ trClass={
+ canOpenNodeDrawer()
+ ? 'cursor-pointer select-none duration-150'
+ : 'select-none duration-150'
+ }
trProps={{
- 'aria-expanded': shouldShowNodeDrawer() ? 'true' : 'false',
+ 'aria-expanded': canOpenNodeDrawer()
+ ? shouldShowNodeDrawer()
+ ? 'true'
+ : 'false'
+ : undefined,
'data-summary-group-id': groupKey(),
'data-summary-group-series-count': String(
groupSummaryScope()?.seriesIds.length ?? 0,
),
'data-summary-row-active': isSummaryGroupHighlighted() ? 'true' : 'false',
- onClick: handleGroupFocusToggle,
+ onClick: canOpenNodeDrawer() ? handleGroupFocusToggle : undefined,
...groupRowInteraction,
}}
/>
diff --git a/frontend-modern/src/components/Workloads/WorkloadsSurface.tsx b/frontend-modern/src/components/Workloads/WorkloadsSurface.tsx
index 6142e0862d..19ae06d6e1 100644
--- a/frontend-modern/src/components/Workloads/WorkloadsSurface.tsx
+++ b/frontend-modern/src/components/Workloads/WorkloadsSurface.tsx
@@ -147,6 +147,7 @@ export function WorkloadsSurface(props: WorkloadsSurfaceProps) {
groupedWindowing={state.groupedWindowing}
guestMetadata={state.guestMetadata}
guestParentNodeMap={state.guestParentNodeMap}
+ groupNodeDrawerMode={state.groupNodeDrawerMode}
groupingMode={state.groupingMode}
handleCustomUrlUpdate={state.handleCustomUrlUpdate}
handleSort={state.handleSort}
diff --git a/frontend-modern/src/components/Workloads/WorkloadsTable.tsx b/frontend-modern/src/components/Workloads/WorkloadsTable.tsx
index 5c4632cda4..95a9f00f04 100644
--- a/frontend-modern/src/components/Workloads/WorkloadsTable.tsx
+++ b/frontend-modern/src/components/Workloads/WorkloadsTable.tsx
@@ -20,6 +20,7 @@ type WorkloadsTableProps = Pick<
| 'groupedWindowing'
| 'guestMetadata'
| 'guestParentNodeMap'
+ | 'groupNodeDrawerMode'
| 'groupingMode'
| 'handleCustomUrlUpdate'
| 'handleSort'
@@ -103,6 +104,7 @@ export function WorkloadsTable(props: WorkloadsTableProps) {
groupedWindowing={props.groupedWindowing}
guestMetadata={props.guestMetadata}
guestParentNodeMap={props.guestParentNodeMap}
+ groupNodeDrawerMode={props.groupNodeDrawerMode}
groupingMode={props.groupingMode}
handleCustomUrlUpdate={props.handleCustomUrlUpdate}
handleTagClick={props.handleTagClick}
diff --git a/frontend-modern/src/components/Workloads/__tests__/WorkloadsSurface.performance.contract.test.tsx b/frontend-modern/src/components/Workloads/__tests__/WorkloadsSurface.performance.contract.test.tsx
index 7940c7327a..d0aa58ff3b 100644
--- a/frontend-modern/src/components/Workloads/__tests__/WorkloadsSurface.performance.contract.test.tsx
+++ b/frontend-modern/src/components/Workloads/__tests__/WorkloadsSurface.performance.contract.test.tsx
@@ -370,7 +370,9 @@ describe('Workloads platform-page embed contract', () => {
expect(stateSource).toContain(
'onMetricDisplayModeChange?: (value: WorkloadsMetricDisplayMode) => void;',
);
- expect(stateSource).toContain('metricHistoryRange?: Accessor;');
+ expect(stateSource).toContain(
+ 'metricHistoryRange?: Accessor;',
+ );
expect(stateSource).toContain(
'onMetricHistoryRangeChange?: (value: WorkloadTableMetricHistoryRange) => void;',
);
@@ -381,17 +383,12 @@ describe('Workloads platform-page embed contract', () => {
// The controls layer must short-circuit to the page-provided accessor +
// change handler when supplied; the internal persistent signal stays as
// the fallback so standalone usage keeps working.
- expect(controlsSource).toContain(
- 'options.metricDisplayMode ?? internalMetricDisplayMode',
- );
+ expect(controlsSource).toContain('options.metricDisplayMode ?? internalMetricDisplayMode');
expect(controlsSource).toContain('options.onMetricDisplayModeChange');
- expect(controlsSource).toContain(
- 'options.metricHistoryRange ?? internalMetricHistoryRange',
- );
+ expect(controlsSource).toContain('options.metricHistoryRange ?? internalMetricHistoryRange');
- const proxmoxSource = (
- await import('../../../features/proxmox/ProxmoxPageSurface.tsx?raw')
- ).default;
+ const proxmoxSource = (await import('../../../features/proxmox/ProxmoxPageSurface.tsx?raw'))
+ .default;
expect(proxmoxSource).toContain('STORAGE_KEYS.WORKLOADS_METRIC_DISPLAY_MODE');
expect(proxmoxSource).toContain('STORAGE_KEYS.WORKLOADS_METRIC_HISTORY_RANGE');
expect(proxmoxSource).toContain('metricDisplayMode={metricDisplayMode}');
@@ -399,9 +396,8 @@ describe('Workloads platform-page embed contract', () => {
expect(proxmoxSource).toContain('metricHistoryRange={metricHistoryRange}');
expect(proxmoxSource).toContain('onMetricHistoryRangeChange={setMetricHistoryRange}');
- const nodesTableSource = (
- await import('../../../features/proxmox/ProxmoxNodesTable.tsx?raw')
- ).default;
+ const nodesTableSource = (await import('../../../features/proxmox/ProxmoxNodesTable.tsx?raw'))
+ .default;
expect(nodesTableSource).toContain('useWorkloadTableMetricHistory');
expect(nodesTableSource).toContain('MetricMiniSparkline');
expect(nodesTableSource).toContain('isSparklineMode');
@@ -410,9 +406,7 @@ describe('Workloads platform-page embed contract', () => {
it('exposes compactGroupHeaders so platform pages can strip duplicate host stats from group rows', async () => {
const stateSource = (await import('../useWorkloadsState.ts?raw')).default;
expect(stateSource).toContain('compactGroupHeaders?: boolean;');
- expect(stateSource).toContain(
- 'compactGroupHeaders: () => props.compactGroupHeaders === true,',
- );
+ expect(stateSource).toContain('compactGroupHeaders: () => props.compactGroupHeaders === true,');
const tableSource = (await import('../WorkloadsTable.tsx?raw')).default;
expect(tableSource).toContain(`| 'compactGroupHeaders'`);
@@ -430,11 +424,36 @@ describe('Workloads platform-page embed contract', () => {
);
expect(panelSource).toContain('!props.compactGroupHeaders() &&');
- const proxmoxSource = (
- await import('../../../features/proxmox/ProxmoxPageSurface.tsx?raw')
- ).default;
+ const proxmoxSource = (await import('../../../features/proxmox/ProxmoxPageSurface.tsx?raw'))
+ .default;
expect(proxmoxSource).toContain('compactGroupHeaders');
});
+
+ it('lets platform pages move grouped host drawers to a dedicated host table owner', async () => {
+ const stateSource = (await import('../useWorkloadsState.ts?raw')).default;
+ expect(stateSource).toContain("groupNodeDrawerMode?: 'inline' | 'disabled';");
+ expect(stateSource).toContain(
+ "groupNodeDrawerMode: () => props.groupNodeDrawerMode ?? 'inline',",
+ );
+
+ const tableSource = (await import('../WorkloadsTable.tsx?raw')).default;
+ expect(tableSource).toContain(`| 'groupNodeDrawerMode'`);
+ expect(tableSource).toContain('groupNodeDrawerMode={props.groupNodeDrawerMode}');
+
+ const panelSource = (await import('../WorkloadPanel.tsx?raw')).default;
+ expect(panelSource).toContain("props.groupNodeDrawerMode() === 'inline'");
+ expect(panelSource).toContain(
+ 'onClick: canOpenNodeDrawer() ? handleGroupFocusToggle : undefined',
+ );
+
+ const proxmoxPageSource = (await import('../../../features/proxmox/ProxmoxPageSurface.tsx?raw'))
+ .default;
+ const proxmoxNodesSource = (await import('../../../features/proxmox/ProxmoxNodesTable.tsx?raw'))
+ .default;
+ expect(proxmoxPageSource).toContain('groupNodeDrawerMode="disabled"');
+ expect(proxmoxNodesSource).toContain('NodeDrawer');
+ expect(proxmoxNodesSource).toContain('data-inline-node-detail-for={node.id}');
+ });
});
describe('Workloads performance contract', () => {
diff --git a/frontend-modern/src/components/Workloads/useWorkloadsState.ts b/frontend-modern/src/components/Workloads/useWorkloadsState.ts
index 22e3907532..97d744db77 100644
--- a/frontend-modern/src/components/Workloads/useWorkloadsState.ts
+++ b/frontend-modern/src/components/Workloads/useWorkloadsState.ts
@@ -79,6 +79,10 @@ export interface WorkloadsSurfaceProps {
// `compactGroupHeaders` strips those stats from the NodeGroupHeader rows
// in grouped mode so the section dividers don't duplicate the info.
compactGroupHeaders?: boolean;
+ // Default Workloads behavior owns grouped host row drawers inline. Platform
+ // pages with a dedicated host table can disable that drawer so host details
+ // open from the host-owned table instead of the embedded guest table.
+ groupNodeDrawerMode?: 'inline' | 'disabled';
// When a platform page owns the metric display mode + sparkline range
// (so the same toggle drives both the page's hosts table and this
// embedded workloads surface), pass the accessors + change handlers.
@@ -454,9 +458,7 @@ export function useWorkloadsState(props: WorkloadsSurfaceProps) {
navigate,
nodeByInstance,
namespaceFilterConfig,
- platformFilterConfig: props.suppressPlatformFilter
- ? () => undefined
- : platformFilterConfig,
+ platformFilterConfig: props.suppressPlatformFilter ? () => undefined : platformFilterConfig,
platformOptions,
reconnect,
reconnectSurface,
@@ -522,6 +524,7 @@ export function useWorkloadsState(props: WorkloadsSurfaceProps) {
ws,
groupingMode,
compactGroupHeaders: () => props.compactGroupHeaders === true,
+ groupNodeDrawerMode: () => props.groupNodeDrawerMode ?? 'inline',
} as const;
}
diff --git a/frontend-modern/src/features/proxmox/ProxmoxNodesTable.tsx b/frontend-modern/src/features/proxmox/ProxmoxNodesTable.tsx
index 609806dac9..ddcb08be1f 100644
--- a/frontend-modern/src/features/proxmox/ProxmoxNodesTable.tsx
+++ b/frontend-modern/src/features/proxmox/ProxmoxNodesTable.tsx
@@ -1,7 +1,16 @@
-import { For, Show, createMemo, type Accessor, type Component, type JSX } from 'solid-js';
+import {
+ For,
+ Show,
+ createMemo,
+ createSignal,
+ type Accessor,
+ type Component,
+ type JSX,
+} from 'solid-js';
import { StatusDot } from '@/components/shared/StatusDot';
import { ResponsiveMetricCell } from '@/components/shared/responsive';
import { TableCard } from '@/components/shared/TableCard';
+import { NodeDrawer } from '@/components/Workloads/NodeDrawer';
import { StackedMemoryBar } from '@/components/Workloads/StackedMemoryBar';
import { StackedDiskBar } from '@/components/Workloads/StackedDiskBar';
import { MetricMiniSparkline } from '@/components/Workloads/MetricMiniSparkline';
@@ -33,6 +42,7 @@ import { type WorkloadsMetricDisplayMode } from '@/components/Workloads/workload
import { type WorkloadTableMetricHistoryRange } from '@/components/Workloads/workloadMetricHistoryModel';
import type { Disk, Node as LegacyNode } from '@/types/api';
import type { Resource } from '@/types/resource';
+import { nodeFromResource } from '@/utils/resourceStateAdapters';
import {
getResourceClusterLabel,
getResourceNodeName,
@@ -128,6 +138,7 @@ export const ProxmoxNodesTable: Component<{
emptyDescription: string;
}> = (props) => {
const breakpoint = useBreakpoint();
+ const [selectedNodeId, setSelectedNodeId] = createSignal(null);
const layoutMode = createMemo(() => getWorkloadTableLayoutMode(breakpoint.width()));
const visibleColumns = createMemo(() => getProxmoxHostVisibleColumnsForLayout(layoutMode()));
const visibleColumnIds = createMemo(() => visibleColumns().map((column) => column.id));
@@ -183,6 +194,18 @@ export const ProxmoxNodesTable: Component<{
{(node) => {
const name = () => asTrimmedString(node.name) || node.id;
+ const drawerNode = () => nodeFromResource(node);
+ const detailRowId = () => `proxmox-host-drawer-${node.id}`;
+ const isSelected = () => selectedNodeId() === node.id;
+ const toggleNodeDrawer = () =>
+ setSelectedNodeId((current) => (current === node.id ? null : node.id));
+ const handleActivationKey: JSX.EventHandler = (
+ event,
+ ) => {
+ if (event.key !== 'Enter' && event.key !== ' ') return;
+ event.preventDefault();
+ toggleNodeDrawer();
+ };
const version = () => asTrimmedString(getResourceVersion(node));
const cluster = () => getResourceClusterLabel(node);
const counts = () => countGuestsForNode(props.guests, getResourceNodeName(node));
@@ -397,9 +420,42 @@ export const ProxmoxNodesTable: Component<{
};
return (
-
- {(column) => renderColumnCell(column)}
-
+ <>
+
+ {(column) => renderColumnCell(column)}
+
+
+ {(selectedNode) => (
+
+
+ event.stopPropagation()}
+ >
+
+
+
+
+ )}
+
+ >
);
}}
diff --git a/frontend-modern/src/features/proxmox/ProxmoxPageSurface.tsx b/frontend-modern/src/features/proxmox/ProxmoxPageSurface.tsx
index f150ac83c3..d8d3e6178d 100644
--- a/frontend-modern/src/features/proxmox/ProxmoxPageSurface.tsx
+++ b/frontend-modern/src/features/proxmox/ProxmoxPageSurface.tsx
@@ -145,6 +145,7 @@ export function ProxmoxPageSurface() {
suppressPlatformFilter
forcedPlatform={PROXMOX_PLATFORM_FILTER}
compactGroupHeaders
+ groupNodeDrawerMode="disabled"
metricDisplayMode={metricDisplayMode}
onMetricDisplayModeChange={setMetricDisplayMode}
metricHistoryRange={metricHistoryRange}
diff --git a/frontend-modern/src/features/proxmox/__tests__/ProxmoxNodesTable.test.tsx b/frontend-modern/src/features/proxmox/__tests__/ProxmoxNodesTable.test.tsx
new file mode 100644
index 0000000000..f9dc680879
--- /dev/null
+++ b/frontend-modern/src/features/proxmox/__tests__/ProxmoxNodesTable.test.tsx
@@ -0,0 +1,102 @@
+import { cleanup, fireEvent, render, screen } from '@solidjs/testing-library';
+import { afterEach, describe, expect, it, vi } from 'vitest';
+
+import type { Resource } from '@/types/resource';
+import { ProxmoxNodesTable } from '../ProxmoxNodesTable';
+
+const nodeDrawerMock = vi.hoisted(() => vi.fn());
+
+vi.mock('@/hooks/useBreakpoint', () => ({
+ useBreakpoint: () => ({
+ width: () => 1280,
+ }),
+}));
+
+vi.mock('@/components/shared/responsive', () => ({
+ ResponsiveMetricCell: () =>
,
+}));
+
+vi.mock('@/components/Workloads/StackedMemoryBar', () => ({
+ StackedMemoryBar: () =>
,
+}));
+
+vi.mock('@/components/Workloads/StackedDiskBar', () => ({
+ StackedDiskBar: () =>
,
+}));
+
+vi.mock('@/components/Workloads/MetricMiniSparkline', () => ({
+ MetricMiniSparkline: () =>
,
+}));
+
+vi.mock('@/components/shared/TemperatureGauge', () => ({
+ TemperatureGauge: () =>
,
+}));
+
+vi.mock('@/components/Workloads/useWorkloadTableMetricHistory', () => ({
+ useWorkloadTableMetricHistory: () => ({
+ getNodeMetricSeries: () => [],
+ }),
+}));
+
+vi.mock('@/components/Workloads/NodeDrawer', () => ({
+ NodeDrawer: (props: { node: { name: string } }) => {
+ nodeDrawerMock(props.node);
+ return {props.node.name}
;
+ },
+}));
+
+const makeNodeResource = (overrides: Partial = {}): Resource => ({
+ id: 'agent:pve-node-1',
+ name: 'pve-node-1',
+ displayName: 'pve-node-1',
+ platformId: 'homelab',
+ platformType: 'proxmox-pve',
+ sourceType: 'hybrid',
+ status: 'online',
+ type: 'agent',
+ lastSeen: 1_700_000_000_000,
+ cpu: { current: 42 },
+ memory: { total: 8_000, used: 3_200, free: 4_800, current: 40 },
+ disk: { total: 10_000, used: 4_500, free: 5_500, current: 45 },
+ proxmox: {
+ clusterName: 'homelab',
+ nodeName: 'pve-node-1',
+ pveVersion: 'pve-manager/9.1.9/ee7bad0a3d1546c9',
+ },
+ ...overrides,
+});
+
+afterEach(() => {
+ cleanup();
+ vi.clearAllMocks();
+});
+
+describe('ProxmoxNodesTable', () => {
+ it('opens the host details drawer from the host-owned top table row', async () => {
+ render(() => (
+ }
+ emptyTitle="No Proxmox VE nodes"
+ emptyDescription="No nodes"
+ />
+ ));
+
+ const row = screen.getByText('pve-node-1').closest('tr');
+ expect(row).toBeTruthy();
+ expect(row).toHaveAttribute('aria-expanded', 'false');
+ expect(screen.queryByTestId('node-drawer')).not.toBeInTheDocument();
+
+ await fireEvent.click(row!);
+
+ expect(row).toHaveAttribute('aria-expanded', 'true');
+ expect(screen.getByTestId('node-drawer')).toHaveTextContent('pve-node-1');
+ expect(nodeDrawerMock).toHaveBeenCalledWith(expect.objectContaining({ name: 'pve-node-1' }));
+
+ await fireEvent.click(row!);
+
+ expect(row).toHaveAttribute('aria-expanded', 'false');
+ expect(screen.queryByTestId('node-drawer')).not.toBeInTheDocument();
+ });
+});
diff --git a/frontend-modern/src/features/proxmox/__tests__/proxmoxDrawerPlacement.contract.test.ts b/frontend-modern/src/features/proxmox/__tests__/proxmoxDrawerPlacement.contract.test.ts
new file mode 100644
index 0000000000..311fe4dfda
--- /dev/null
+++ b/frontend-modern/src/features/proxmox/__tests__/proxmoxDrawerPlacement.contract.test.ts
@@ -0,0 +1,25 @@
+import { describe, expect, it } from 'vitest';
+
+import workloadsStateSource from '@/components/Workloads/useWorkloadsState.ts?raw';
+import workloadPanelSource from '@/components/Workloads/WorkloadPanel.tsx?raw';
+import workloadsTableSource from '@/components/Workloads/WorkloadsTable.tsx?raw';
+import proxmoxNodesTableSource from '../ProxmoxNodesTable.tsx?raw';
+import proxmoxPageSurfaceSource from '../ProxmoxPageSurface.tsx?raw';
+
+describe('Proxmox drawer placement contract', () => {
+ it('keeps host details owned by the Proxmox host table instead of the embedded guest table', () => {
+ expect(workloadsStateSource).toContain("groupNodeDrawerMode?: 'inline' | 'disabled';");
+ expect(workloadsStateSource).toContain(
+ "groupNodeDrawerMode: () => props.groupNodeDrawerMode ?? 'inline',",
+ );
+ expect(workloadsTableSource).toContain(`| 'groupNodeDrawerMode'`);
+ expect(workloadsTableSource).toContain('groupNodeDrawerMode={props.groupNodeDrawerMode}');
+ expect(workloadPanelSource).toContain("props.groupNodeDrawerMode() === 'inline'");
+ expect(workloadPanelSource).toContain(
+ 'onClick: canOpenNodeDrawer() ? handleGroupFocusToggle : undefined',
+ );
+ expect(proxmoxPageSurfaceSource).toContain('groupNodeDrawerMode="disabled"');
+ expect(proxmoxNodesTableSource).toContain('NodeDrawer');
+ expect(proxmoxNodesTableSource).toContain('data-inline-node-detail-for={node.id}');
+ });
+});
diff --git a/frontend-modern/src/features/proxmox/__tests__/proxmoxHostTableModel.test.ts b/frontend-modern/src/features/proxmox/__tests__/proxmoxHostTableModel.test.ts
index 6ea6455da1..76a11d0fe6 100644
--- a/frontend-modern/src/features/proxmox/__tests__/proxmoxHostTableModel.test.ts
+++ b/frontend-modern/src/features/proxmox/__tests__/proxmoxHostTableModel.test.ts
@@ -13,10 +13,10 @@ describe('proxmoxHostTableModel', () => {
expect(ids).toEqual(['node', 'cpu', 'memory', 'disk']);
expect(getProxmoxHostTableMinWidthClass('mobile')).toBe('min-w-full');
- expect(getProxmoxHostColumnWidthStyle('node', 'mobile', ids)).toEqual({ width: '38%' });
- expect(getProxmoxHostColumnWidthStyle('cpu', 'mobile', ids)).toEqual({ width: '20%' });
- expect(getProxmoxHostColumnWidthStyle('memory', 'mobile', ids)).toEqual({ width: '21%' });
- expect(getProxmoxHostColumnWidthStyle('disk', 'mobile', ids)).toEqual({ width: '21%' });
+ expect(getProxmoxHostColumnWidthStyle('node', 'mobile', ids)).toEqual({ width: '44%' });
+ expect(getProxmoxHostColumnWidthStyle('cpu', 'mobile', ids)).toEqual({ width: '23%' });
+ expect(getProxmoxHostColumnWidthStyle('memory', 'mobile', ids)).toEqual({ width: '23%' });
+ expect(getProxmoxHostColumnWidthStyle('disk', 'mobile', ids)).toEqual({ width: '10%' });
});
it('adds temperature and guest counts before slower-changing metadata on tablet', () => {
@@ -50,7 +50,7 @@ describe('proxmoxHostTableModel', () => {
expect(getProxmoxHostTableMinWidthClass('compact')).toBe('min-w-[1080px]');
expect(getProxmoxHostTableMinWidthClass('wide')).toBe('min-w-[1080px]');
expect(getProxmoxHostColumnWidthStyle('cluster', 'compact', compactIds)).toEqual({
- width: '12%',
+ width: '13.0435%',
});
});
});