Keep Standalone availability checks in focused tab

This commit is contained in:
rcourtman 2026-05-25 17:51:09 +01:00
parent 697634da76
commit ed67706824
3 changed files with 58 additions and 15 deletions

View file

@ -3586,3 +3586,7 @@ frontend-primitives-owned Standalone surface rather than a new primary nav item.
The page may show availability checks beside standalone Pulse Agent machines and
provide a focused availability tab, but Settings remains the add/edit owner and
the app shell must not add a separate top-level Availability destination.
The Standalone overview must not duplicate the focused availability table:
overview may show standalone Pulse Agent machines and a compact handoff when an
estate only has agentless checks, while the full availability-check row list
belongs to the Availability checks tab.

View file

@ -27,6 +27,8 @@ type StandaloneTabId = (typeof STANDALONE_TAB_SPECS)[number]['id'];
const machineIcon = () => <ServerIcon class="h-6 w-6 text-slate-400" />;
const availabilityIcon = () => <ActivityIcon class="h-6 w-6 text-slate-400" />;
const overviewActionClass =
'inline-flex items-center gap-2 rounded-md border border-border bg-surface px-3 py-1.5 text-xs font-medium text-base-content shadow-sm hover:bg-slate-50';
const resolveStandaloneTab = (pathname: string): StandaloneTabId =>
pathname.replace(/\/+$/, '') === buildStandalonePath('availability')
@ -134,7 +136,24 @@ export function StandalonePageSurface() {
}
>
<div class="space-y-4">
<Show when={model().machines.length > 0}>
<Show
when={model().machines.length > 0}
fallback={
<Show when={model().availabilityChecks.length > 0}>
<PlatformTableEmptyState
icon={machineIcon()}
title="No standalone Pulse Agent machines"
description="Agentless devices and services are monitored from the Availability checks tab."
actions={
<A href={buildStandalonePath('availability')} class={overviewActionClass}>
<ActivityIcon class="h-3.5 w-3.5" />
View checks
</A>
}
/>
</Show>
}
>
<AgentsMachinesTable
resources={model().machines}
emptyIcon={machineIcon()}
@ -142,14 +161,6 @@ export function StandalonePageSurface() {
emptyDescription="Install the Pulse Agent on Linux, macOS, Windows, or Unraid systems that are not already represented by a platform integration."
/>
</Show>
<Show when={model().availabilityChecks.length > 0}>
<AvailabilityChecksTable
resources={model().availabilityChecks}
emptyIcon={availabilityIcon()}
emptyTitle="No availability checks"
emptyDescription="Add ping, TCP, MQTT, ESPHome, or HTTP checks for devices and services that cannot run Pulse Agent."
/>
</Show>
</div>
</Show>
</Show>

View file

@ -55,7 +55,12 @@ vi.mock('@/features/platformPage/sharedPlatformPage', () => ({
data-tabs={props.tabs.map((tab) => tab.id).join(',')}
/>
),
PlatformTableEmptyState: () => <div data-testid="platform-table-empty-state" />,
PlatformTableEmptyState: (props: { title: string; actions?: JSX.Element }) => (
<div data-testid="platform-table-empty-state">
<span>{props.title}</span>
{props.actions}
</div>
),
PlatformTableLoadingState: () => <div data-testid="platform-table-loading-state" />,
}));
@ -97,7 +102,7 @@ afterEach(() => {
});
describe('StandalonePageSurface', () => {
it('loads standalone machines and agentless availability checks into the Standalone surface', () => {
it('keeps overview focused on standalone machines without duplicating availability rows', () => {
render(() => <StandalonePageSurface />);
expect(mocks.useUnifiedResources).toHaveBeenCalledWith(
@ -113,10 +118,7 @@ describe('StandalonePageSurface', () => {
'data-resource-count',
'1',
);
expect(screen.getByTestId('availability-checks-table')).toHaveAttribute(
'data-resource-count',
'1',
);
expect(screen.queryByTestId('availability-checks-table')).not.toBeInTheDocument();
});
it('uses the availability tab as a focused check monitor', () => {
@ -134,4 +136,30 @@ describe('StandalonePageSurface', () => {
'1',
);
});
it('uses an overview handoff when only agentless availability checks are present', () => {
mocks.useUnifiedResources.mockReturnValue({
resources: () => [
resource({
id: 'mqtt-meter',
type: 'network-endpoint',
platformType: 'availability',
sources: ['availability'],
}),
],
loading: () => false,
error: () => null,
refetch: vi.fn(),
});
render(() => <StandalonePageSurface />);
expect(screen.queryByTestId('agents-machines-table')).not.toBeInTheDocument();
expect(screen.queryByTestId('availability-checks-table')).not.toBeInTheDocument();
expect(screen.getByText('No standalone Pulse Agent machines')).toBeInTheDocument();
expect(screen.getByRole('link', { name: 'View checks' })).toHaveAttribute(
'href',
'/standalone/availability',
);
});
});