From f754dfa9b9cbfa5745f8bd475b3793ba1d5bb863 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Sat, 18 Apr 2026 21:33:37 +0100 Subject: [PATCH] Redesign infrastructure settings around one ledger --- .../v6/internal/subsystems/agent-lifecycle.md | 28 +-- .../subsystems/frontend-primitives.md | 12 +- .../components/Settings/ConnectionsTable.tsx | 2 +- .../InfrastructureActiveRowDetails.tsx | 4 +- .../Settings/InfrastructureWorkspace.tsx | 165 +++++++++++++----- .../__tests__/ConnectionsTable.test.tsx | 4 +- ...nfrastructureOperationsController.test.tsx | 8 +- .../InfrastructureWorkspace.test.tsx | 78 ++++++--- .../__tests__/settingsArchitecture.test.ts | 16 +- .../components/Settings/settingsHeaderMeta.ts | 6 +- 10 files changed, 220 insertions(+), 103 deletions(-) diff --git a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md index 09abb9c23..cd8833e4f 100644 --- a/docs/release-control/v6/internal/subsystems/agent-lifecycle.md +++ b/docs/release-control/v6/internal/subsystems/agent-lifecycle.md @@ -858,19 +858,21 @@ ledger. Inline detail drawers may surface reporting-item and ignored-item controls, but installer setup, platform-specific configuration, and profile management must remain secondary flows rather than being dumped underneath the default ledger. -Those secondary infrastructure views must also replace the workspace body -rather than stacking beneath the systems ledger. When the operator opens -platform connection management, install tooling, or the legacy operations -workspace route, `InfrastructureWorkspace.tsx` must not keep the systems table -mounted above that second surface. -That infrastructure surface must now stay single-purpose per workspace route: -the default systems view owns the top-level monitored-system ledger, the -connections view owns API-backed platform management, and the install view -owns Linux/Windows/macOS/FreeBSD command generation. The shared Settings -sidebar owns only the top-level `Infrastructure` destination; movement between -those three jobs belongs to the primary workspace subtabs rendered inside -`InfrastructureWorkspace.tsx`, and selecting one subtab must replace the body -instead of stacking another surface underneath it. +Those secondary infrastructure views must open through route-backed drawers +rather than replacing the ledger body or stacking beneath it. When the +operator opens platform connection management, install tooling, or the legacy +operations workspace route, `InfrastructureWorkspace.tsx` must keep the same +top-level systems ledger anchored in place and layer the secondary surface in a +drawer that can close back to `/settings/infrastructure` without trapping the +user. +That infrastructure surface must now stay single-purpose per route-backed +drawer: the default systems view owns the top-level monitored-system ledger, +the connections drawer owns API-backed platform management, and the install +drawer owns Linux/Windows/macOS/FreeBSD command generation. The shared +Settings sidebar owns only the top-level `Infrastructure` destination; movement +between those three jobs belongs to explicit drawer actions inside +`InfrastructureWorkspace.tsx`, not extra sidebar entries or body-replacing +workspace subtabs. That same lifecycle-owned platform-connections workspace must keep API-backed provider state operationally useful, not CRUD-only. `TrueNASSettingsPanel.tsx` and `useTrueNASSettingsPanelState.ts` must surface the shared runtime health, diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md index bada6530a..7a1461775 100644 --- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md +++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md @@ -222,14 +222,14 @@ work extends shared components instead of creating new local variants. workspaces, and profile management remain secondary flows opened by explicit deep links or drawers instead of being dumped inline underneath the default table. - Those deep-linked secondary views must replace the body below the shared - page header instead of keeping the systems ledger mounted above them, so the - same system or connection context is not duplicated once in the default - ledger and again inside a secondary management workspace. + Those deep-linked secondary views must keep the systems ledger mounted and + open inside route-backed drawers instead of replacing the page body or + stacking another inline workspace underneath it, so the operator always + stays anchored to the same canonical ledger while managing setup flows. That same shared shell boundary now owns one canonical infrastructure destination in the Settings sidebar. `InfrastructureWorkspace.tsx` owns the - primary `Systems`, `Connections`, and `Install` workspace subtabs inside - that destination, while each selected route body still stays + one default ledger plus route-backed `Connections` and `Install` drawers + inside that destination, while each secondary flow still stays single-purpose instead of stacking multiple workspace surfaces at once. 6. Keep Proxmox deep-link route selection on the shared settings-navigation boundary. `frontend-modern/src/components/Settings/settingsNavigationModel.ts` and `frontend-modern/src/components/Settings/useSettingsNavigation.ts` must treat the canonical PBS and PMG Proxmox deep links as agent-selection authority even though those URLs resolve to the shared `infrastructure-operations` tab. Reloading or remounting on a PBS or PMG deep link must not silently fall back to the PVE selector state. 7. Keep shared storage feature presenters on canonical platform truth. When reusable storage presenters under `frontend-modern/src/features/storageBackups/` classify canonical resources for the shared storage route, API-backed virtualization datastores such as VMware must stay inventory-only datastores instead of inheriting PBS-specific backup-repository or protected-target copy from older fallback branches. diff --git a/frontend-modern/src/components/Settings/ConnectionsTable.tsx b/frontend-modern/src/components/Settings/ConnectionsTable.tsx index 09c8bfae7..aa54f1eac 100644 --- a/frontend-modern/src/components/Settings/ConnectionsTable.tsx +++ b/frontend-modern/src/components/Settings/ConnectionsTable.tsx @@ -27,7 +27,7 @@ export const ConnectionsTable: Component = (props) => {
-

Systems

+

Monitored systems

One row per top-level monitored system.

0}> diff --git a/frontend-modern/src/components/Settings/InfrastructureActiveRowDetails.tsx b/frontend-modern/src/components/Settings/InfrastructureActiveRowDetails.tsx index 75ee8f19c..a039e0a72 100644 --- a/frontend-modern/src/components/Settings/InfrastructureActiveRowDetails.tsx +++ b/frontend-modern/src/components/Settings/InfrastructureActiveRowDetails.tsx @@ -314,11 +314,11 @@ export const InfrastructureActiveRowDetails: Component { event.stopPropagation(); - navigate(path()); + navigate(path(), { scroll: false }); }} class="inline-flex min-h-9 items-center rounded-md px-2.5 py-1.5 text-xs font-medium text-blue-600 hover:bg-blue-50 hover:text-blue-900 dark:text-blue-400 dark:hover:bg-blue-900 dark:hover:text-blue-300" > - Open platform connections + Manage connection )} diff --git a/frontend-modern/src/components/Settings/InfrastructureWorkspace.tsx b/frontend-modern/src/components/Settings/InfrastructureWorkspace.tsx index 459e03a24..e0f2c6cd7 100644 --- a/frontend-modern/src/components/Settings/InfrastructureWorkspace.tsx +++ b/frontend-modern/src/components/Settings/InfrastructureWorkspace.tsx @@ -1,7 +1,6 @@ -import { Component, Match, Show, Switch, createEffect, createMemo, createSignal } from 'solid-js'; +import { Component, Show, createEffect, createMemo, createSignal } from 'solid-js'; import { useLocation, useNavigate } from '@solidjs/router'; import { Dialog } from '@/components/shared/Dialog'; -import { Subtabs } from '@/components/shared/Subtabs'; import { presentationPolicyIsReadOnly } from '@/stores/sessionPresentationPolicy'; import { AgentProfilesPanel } from './AgentProfilesPanel'; import { AddSystemPicker, type AddSystemChoice } from './AddSystemPicker'; @@ -19,7 +18,6 @@ import { PlatformConnectionsWorkspace } from './PlatformConnectionsWorkspace'; import { buildInfrastructureWorkspacePath, getInfrastructureWorkspaceViewFromPath, - type InfrastructureWorkspaceView, } from './infrastructureWorkspaceModel'; import type { InfrastructurePlatformSettingsProps } from './proxmoxSettingsModel'; import { @@ -52,23 +50,36 @@ const InfrastructureWorkspaceContent: Component = readOnlyWorkspace() ? [] : [ + { + label: 'Connections', + onSelect: () => navigate(buildInfrastructureWorkspacePath('platforms'), { scroll: false }), + tone: 'secondary' as const, + }, { label: 'Agent profiles', onSelect: () => setProfilesOpen(true), tone: 'secondary' as const, }, { - label: '+ Add a system', + label: 'Add infrastructure', onSelect: () => setPickerOpen(true), tone: 'primary' as const, }, ], ); - const workspaceTabs = createMemo(() => [ - { value: 'inventory', label: 'Systems' }, - { value: 'platforms', label: 'Connections' }, - { value: 'install', label: 'Install' }, - ]); + const closeConnectionsWorkspace = () => { + props.trueNASSettings.closeDialog?.(); + props.trueNASSettings.closeDeleteDialog?.(); + props.vmwareSettings.closeDialog?.(); + props.vmwareSettings.closeDeleteDialog?.(); + props.setShowNodeModal(false); + props.setEditingNode(null); + props.cancelDeleteNode?.(); + navigate(buildInfrastructureWorkspacePath('inventory'), { scroll: false }); + }; + const closeInstallWorkspace = () => { + navigate(buildInfrastructureWorkspacePath('inventory'), { scroll: false }); + }; const openProxmoxNode = (nodeKind: 'pve' | 'pbs' | 'pmg', nodeId: string) => { const nodes = @@ -84,26 +95,26 @@ const InfrastructureWorkspaceContent: Component = props.setEditingNode(node); props.setModalResetKey((value) => value + 1); props.setShowNodeModal(true); - navigate(proxmoxRouteForKind(nodeKind)); + navigate(proxmoxRouteForKind(nodeKind), { scroll: false }); }; const handleAddSystem = (choice: AddSystemChoice) => { setPickerOpen(false); if (choice.kind === 'agent') { - navigate(buildInfrastructureWorkspacePath('install')); + navigate(buildInfrastructureWorkspacePath('install'), { scroll: false }); return; } if (choice.kind === 'truenas') { props.trueNASSettings.openCreateDialog(); - navigate('/settings/infrastructure/platforms/truenas'); + navigate('/settings/infrastructure/platforms/truenas', { scroll: false }); return; } if (choice.kind === 'vmware') { props.vmwareSettings.openCreateDialog(); - navigate('/settings/infrastructure/platforms/vmware'); + navigate('/settings/infrastructure/platforms/vmware', { scroll: false }); return; } @@ -131,26 +142,23 @@ const InfrastructureWorkspaceContent: Component = } }); + createEffect(() => { + if (activeView() === 'inventory') { + return; + } + setPickerOpen(false); + setProfilesOpen(false); + state.setExpandedRowKey(null); + state.setSelectedIgnoredRowKey(null); + }); + return (
- - - navigate(buildInfrastructureWorkspacePath(value as InfrastructureWorkspaceView)) - } - ariaLabel="Infrastructure workspace" - tabs={workspaceTabs()} - /> - - - - handleManageAction(row.manage)} - /> - + handleManageAction(row.manage)} + /> =
+ +
+
+
+
+
+ Connections +
+
Platform connections
+
+ Configure API-backed providers without leaving the infrastructure ledger. +
+
+ +
+
+
+ +
+
+
+ + +
+
+
+
+
+ Install +
+
Install Pulse agent
+
+ Generate Linux, macOS, FreeBSD, and Windows install commands from the same + workspace. +
+
+ +
+
+
+ +
+
+
+ state.setExpandedRowKey(null)} @@ -195,16 +288,6 @@ const InfrastructureWorkspaceContent: Component = {(rowAccessor) => } - - - - - - - - - -
); }; diff --git a/frontend-modern/src/components/Settings/__tests__/ConnectionsTable.test.tsx b/frontend-modern/src/components/Settings/__tests__/ConnectionsTable.test.tsx index dcb7b497c..ee46d0184 100644 --- a/frontend-modern/src/components/Settings/__tests__/ConnectionsTable.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/ConnectionsTable.test.tsx @@ -69,7 +69,7 @@ describe('ConnectionsTable', () => { rows={() => []} headerActions={[ { - label: '+ Add a system', + label: 'Add infrastructure', onSelect: onAddSystem, tone: 'primary', }, @@ -83,7 +83,7 @@ describe('ConnectionsTable', () => { ) as any); expect(screen.getByRole('button', { name: 'Agent profiles' })).toBeInTheDocument(); - const button = screen.getByRole('button', { name: /\+ Add a system/i }); + const button = screen.getByRole('button', { name: /Add infrastructure/i }); fireEvent.click(button); expect(onAddSystem).toHaveBeenCalledTimes(1); }); diff --git a/frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsController.test.tsx b/frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsController.test.tsx index 880ce2227..d1ce389d6 100644 --- a/frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsController.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/InfrastructureOperationsController.test.tsx @@ -1231,7 +1231,7 @@ describe('InfrastructureOperationsController managed agents table', () => { expect(details.getByText('Docker runtime ID')).toBeInTheDocument(); expect(details.getByText('Node ID')).toBeInTheDocument(); expect(details.getAllByText('delly-resource').length).toBeGreaterThan(0); - expect(details.getByRole('button', { name: /Open platform connections/i })).toBeInTheDocument(); + expect(details.getByRole('button', { name: /Manage connection/i })).toBeInTheDocument(); expect(details.getAllByText('delly-agent').length).toBeGreaterThan(0); expect(details.getAllByText('delly-docker').length).toBeGreaterThan(0); }); @@ -1282,11 +1282,13 @@ describe('InfrastructureOperationsController managed agents table', () => { ).not.toBeInTheDocument(); const openPlatformConnectionsButton = details.getByRole('button', { - name: /Open platform connections/i, + name: /Manage connection/i, }); fireEvent.click(openPlatformConnectionsButton); - expect(navigateMock).toHaveBeenCalledWith('/settings/infrastructure/platforms/truenas'); + expect(navigateMock).toHaveBeenCalledWith('/settings/infrastructure/platforms/truenas', { + scroll: false, + }); }); it('distinguishes PBS coverage from Proxmox nodes on non-Proxmox hosts', async () => { diff --git a/frontend-modern/src/components/Settings/__tests__/InfrastructureWorkspace.test.tsx b/frontend-modern/src/components/Settings/__tests__/InfrastructureWorkspace.test.tsx index f168640c9..bc97c9000 100644 --- a/frontend-modern/src/components/Settings/__tests__/InfrastructureWorkspace.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/InfrastructureWorkspace.test.tsx @@ -48,10 +48,6 @@ vi.mock('../useInfrastructureOperationsState', () => ({ }), })); -vi.mock('../InfrastructureInventorySection', () => ({ - InfrastructureInventorySection: () =>
inventory
, -})); - vi.mock('../InfrastructureInstallerSection', () => ({ InfrastructureInstallerSection: () =>
install
, })); @@ -121,11 +117,15 @@ const baseProps = () => trueNASSettings: { connections: () => [{ id: 'tn-1', name: 'Tower NAS', host: '10.0.0.20', enabled: true }], openCreateDialog: trueNASOpenCreateDialogSpy, + closeDialog: vi.fn(), + closeDeleteDialog: vi.fn(), openEditDialog: vi.fn(), }, vmwareSettings: { connections: () => [{ id: 'vm-1', name: 'lab-vcenter', host: '10.0.0.30', enabled: true }], openCreateDialog: vmwareOpenCreateDialogSpy, + closeDialog: vi.fn(), + closeDeleteDialog: vi.fn(), openEditDialog: vi.fn(), }, selectedAgent: () => 'pve', @@ -167,10 +167,9 @@ describe('InfrastructureWorkspace', () => { it('renders only the top-level ledger at the base infrastructure route', () => { renderWorkspace(); - expect(screen.getByRole('heading', { name: 'Systems' })).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: 'Monitored systems' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Connections' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Agent profiles' })).toBeInTheDocument(); - expect(screen.queryByRole('button', { name: 'Manage connections' })).toBeNull(); - expect(screen.queryByTestId('inventory-section')).toBeNull(); expect(screen.queryByTestId('platform-section')).toBeNull(); expect(screen.queryByTestId('install-section')).toBeNull(); expect(screen.queryByTestId('agent-profiles')).toBeNull(); @@ -188,7 +187,7 @@ describe('InfrastructureWorkspace', () => { it('opens the add-system picker when the add button is clicked', () => { renderWorkspace(); - fireEvent.click(screen.getByRole('button', { name: /\+ Add a system/i })); + fireEvent.click(screen.getByRole('button', { name: /Add infrastructure/i })); expect(screen.getByText('Install on a host')).toBeInTheDocument(); expect(screen.getByText('Proxmox VE')).toBeInTheDocument(); @@ -197,37 +196,45 @@ describe('InfrastructureWorkspace', () => { it('routes the agent-host choice to the install section deep link', () => { renderWorkspace(); - fireEvent.click(screen.getByRole('button', { name: /\+ Add a system/i })); + fireEvent.click(screen.getByRole('button', { name: /Add infrastructure/i })); fireEvent.click(screen.getByText('Install on a host')); - expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure/install'); + expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure/install', { + scroll: false, + }); }); it('opens provider creation flows directly from the add-system picker', () => { renderWorkspace(); - fireEvent.click(screen.getByRole('button', { name: /\+ Add a system/i })); + fireEvent.click(screen.getByRole('button', { name: /Add infrastructure/i })); fireEvent.click(screen.getByText('TrueNAS SCALE')); expect(trueNASOpenCreateDialogSpy).toHaveBeenCalledTimes(1); - expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure/platforms/truenas'); + expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure/platforms/truenas', { + scroll: false, + }); - fireEvent.click(screen.getByRole('button', { name: /\+ Add a system/i })); + fireEvent.click(screen.getByRole('button', { name: /Add infrastructure/i })); fireEvent.click(screen.getByText('VMware vSphere or ESXi')); expect(vmwareOpenCreateDialogSpy).toHaveBeenCalledTimes(1); - expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure/platforms/vmware'); + expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure/platforms/vmware', { + scroll: false, + }); }); it('opens the proxmox node modal directly from the add-system picker', () => { renderWorkspace(); - fireEvent.click(screen.getByRole('button', { name: /\+ Add a system/i })); + fireEvent.click(screen.getByRole('button', { name: /Add infrastructure/i })); fireEvent.click(screen.getByText('Proxmox VE')); expect(onSelectAgentSpy).toHaveBeenCalledWith('pve'); expect(setCurrentNodeTypeSpy).toHaveBeenCalledWith('pve'); expect(setEditingNodeSpy).toHaveBeenCalledWith(null); expect(setShowNodeModalSpy).toHaveBeenCalledWith(true); - expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure/platforms/proxmox/pve'); + expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure/platforms/proxmox/pve', { + scroll: false, + }); }); it('opens reporting details from the top ledger in a drawer', () => { @@ -239,28 +246,47 @@ describe('InfrastructureWorkspace', () => { expect(screen.getByTestId('active-details')).toBeInTheDocument(); }); - it('shows only platform setup below the ledger on platform deep links', () => { + it('keeps the ledger visible and opens platform setup in a drawer on platform deep links', () => { mockPathname = '/settings/infrastructure/platforms/truenas'; renderWorkspace(); - expect(screen.queryByRole('heading', { name: 'Systems' })).toBeNull(); + expect(screen.getByRole('heading', { name: 'Monitored systems' })).toBeInTheDocument(); + expect(screen.getByText('Platform connections')).toBeInTheDocument(); expect(screen.getByTestId('platform-section')).toBeInTheDocument(); - expect(screen.queryByTestId('inventory-section')).toBeNull(); expect(screen.queryByTestId('install-section')).toBeNull(); - expect(screen.queryByRole('button', { name: 'Agent profiles' })).toBeNull(); - expect(screen.queryByTestId('agent-profiles')).toBeNull(); }); - it('shows only install tools below the ledger on install deep links', () => { + it('keeps the ledger visible and opens install tools in a drawer on install deep links', () => { mockPathname = '/settings/infrastructure/install'; renderWorkspace(); - expect(screen.queryByRole('heading', { name: 'Systems' })).toBeNull(); + expect(screen.getByRole('heading', { name: 'Monitored systems' })).toBeInTheDocument(); + expect(screen.getByText('Install Pulse agent')).toBeInTheDocument(); expect(screen.getByTestId('install-section')).toBeInTheDocument(); - expect(screen.queryByTestId('inventory-section')).toBeNull(); expect(screen.queryByTestId('platform-section')).toBeNull(); }); + it('opens the platform connections drawer from the header action', () => { + renderWorkspace(); + + fireEvent.click(screen.getByRole('button', { name: 'Connections' })); + + expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure/platforms', { + scroll: false, + }); + }); + + it('closes the platform drawer back to the ledger route', () => { + mockPathname = '/settings/infrastructure/platforms/truenas'; + renderWorkspace(); + + fireEvent.click(screen.getAllByRole('button', { name: 'Close' })[0]); + + expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure', { + scroll: false, + }); + }); + it('opens agent profiles in a dedicated drawer instead of inline', () => { renderWorkspace(); @@ -275,11 +301,11 @@ describe('InfrastructureWorkspace', () => { renderWorkspace(); expect(navigateSpy).toHaveBeenCalledWith('/settings/infrastructure', { replace: true }); - expect(screen.queryByRole('button', { name: /\+ Add a system/i })).toBeNull(); + expect(screen.queryByRole('button', { name: /Add infrastructure/i })).toBeNull(); + expect(screen.queryByRole('button', { name: 'Connections' })).toBeNull(); expect(screen.queryByRole('button', { name: 'Agent profiles' })).toBeNull(); expect(screen.queryByTestId('platform-section')).toBeNull(); expect(screen.queryByTestId('install-section')).toBeNull(); expect(screen.queryByTestId('agent-profiles')).toBeNull(); - expect(screen.queryByTestId('inventory-section')).toBeNull(); }); }); diff --git a/frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts b/frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts index 214aae879..6c99706ee 100644 --- a/frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts +++ b/frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts @@ -898,11 +898,15 @@ describe('Settings architecture guardrails', () => { expect(infrastructureWorkspaceSource).toContain('InfrastructureStopMonitoringDialog'); expect(infrastructureWorkspaceSource).toContain('AgentProfilesPanel'); expect(infrastructureWorkspaceSource).toContain('PlatformConnectionsWorkspace'); - expect(infrastructureWorkspaceSource).toContain("import { Subtabs } from '@/components/shared/Subtabs'"); - expect(infrastructureWorkspaceSource).toContain(' { ); expect(SETTINGS_HEADER_META['infrastructure-systems'].title).toBe('Infrastructure'); expect(SETTINGS_HEADER_META['infrastructure-systems'].description).toContain( - 'manage platform connections', + 'open drawers for platform connections', ); expect(SETTINGS_HEADER_META['infrastructure-systems'].description).toBe( - `Review monitored systems, manage platform connections, and install Pulse agents from one workspace. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`, + `Review top-level monitored systems from one ledger, then open drawers for platform connections, install commands, and agent profiles. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`, ); expect(SETTINGS_HEADER_META['infrastructure-connections'].title).toBe('Infrastructure'); expect(SETTINGS_HEADER_META['infrastructure-install'].title).toBe('Infrastructure'); diff --git a/frontend-modern/src/components/Settings/settingsHeaderMeta.ts b/frontend-modern/src/components/Settings/settingsHeaderMeta.ts index adc2c2638..4d4642a8c 100644 --- a/frontend-modern/src/components/Settings/settingsHeaderMeta.ts +++ b/frontend-modern/src/components/Settings/settingsHeaderMeta.ts @@ -10,17 +10,17 @@ export const SETTINGS_HEADER_META: SettingsHeaderMetaMap = { 'infrastructure-systems': { title: 'Infrastructure', description: - `Review monitored systems, manage platform connections, and install Pulse agents from one workspace. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`, + `Review top-level monitored systems from one ledger, then open drawers for platform connections, install commands, and agent profiles. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`, }, 'infrastructure-connections': { title: 'Infrastructure', description: - `Review monitored systems, manage platform connections, and install Pulse agents from one workspace. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`, + `Review top-level monitored systems from one ledger, then open drawers for platform connections, install commands, and agent profiles. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`, }, 'infrastructure-install': { title: 'Infrastructure', description: - `Review monitored systems, manage platform connections, and install Pulse agents from one workspace. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`, + `Review top-level monitored systems from one ledger, then open drawers for platform connections, install commands, and agent profiles. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`, }, 'system-general': { title: 'General',