diff --git a/docs/release-control/v6/internal/subsystems/cloud-paid.md b/docs/release-control/v6/internal/subsystems/cloud-paid.md index 520f12d3cf..ac45b68e9d 100644 --- a/docs/release-control/v6/internal/subsystems/cloud-paid.md +++ b/docs/release-control/v6/internal/subsystems/cloud-paid.md @@ -1122,6 +1122,10 @@ default billing and pricing surfaces should use concise monitored-system copy, while the full counted-unit definition appears only behind explicit disclosure such as `View counting rules` instead of sitting as always-visible explanatory chrome. +When a self-hosted billing arrival is explicitly about monitored-system +capacity, `ProLicensePlanSection.tsx` may still open that disclosure by +default, but the same top-level-root definition must remain the canonical +counted-unit explanation rather than introducing a second plan-local wording. The same boundary also owns the warning-banner shorthand: customer-facing monitored-system warnings should describe the current counted total in plain language such as `16 monitored systems currently counted`, and any Community diff --git a/frontend-modern/src/components/Settings/ProLicensePlanSection.tsx b/frontend-modern/src/components/Settings/ProLicensePlanSection.tsx index f990ce61a2..39eebb937c 100644 --- a/frontend-modern/src/components/Settings/ProLicensePlanSection.tsx +++ b/frontend-modern/src/components/Settings/ProLicensePlanSection.tsx @@ -1,6 +1,7 @@ import { Component, For, Show } from 'solid-js'; import RefreshCw from 'lucide-solid/icons/refresh-cw'; import { UpgradeLink } from '@/components/shared/UpgradeLink'; +import { MonitoredSystemDefinitionDisclosure } from '@/components/Commercial/MonitoredSystemDefinitionDisclosure'; import { getUpgradeActionDestination } from '@/stores/licenseCommercial'; import { licenseEntitlementsLoadError } from '@/stores/licenseEntitlements'; import { @@ -104,6 +105,12 @@ export const ProLicensePlanSection: Component = (pro +
+ +
{(notice) => (
diff --git a/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx b/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx index fd783e9280..32f5baf6fc 100644 --- a/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx +++ b/frontend-modern/src/components/Settings/__tests__/ProLicensePanel.test.tsx @@ -660,12 +660,37 @@ describe('ProLicensePanel', () => { renderPanel(); expect(screen.getByText('Need a higher monitored-system cap?')).toBeInTheDocument(); + expect( + screen.getByText( + 'Pulse counts top-level monitored systems such as Docker hosts, Kubernetes clusters, Proxmox nodes, standalone hosts, and TrueNAS systems. Compare self-hosted plans in Pulse Account and return here with Pulse Pro activated automatically.', + ), + ).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Hide counting rules' })).toBeInTheDocument(); + expect( + screen.getByText( + /a monitored system is a top-level monitored root such as a docker host, kubernetes cluster, proxmox node/i, + ), + ).toBeInTheDocument(); expect(screen.getByRole('link', { name: 'Compare plans' })).toHaveAttribute( 'href', getSelfHostedPurchaseStartUrl('max_monitored_systems'), ); }); + it('keeps monitored-system counting guidance available on the plan surface', async () => { + renderPanel(); + + expect( + screen.getByText('Pulse counts top-level monitored systems. Child resources underneath them are included.'), + ).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'View counting rules' })).toBeInTheDocument(); + expect( + screen.queryByText( + /a monitored system is a top-level monitored root such as a docker host, kubernetes cluster, proxmox node/i, + ), + ).not.toBeInTheDocument(); + }); + it('navigates between plan and usage focus states through the billing subtabs', async () => { useLocationMock.mockReturnValue({ search: '', @@ -848,6 +873,7 @@ describe('ProLicensePanel', () => { expect(proLicensePlanSectionSource).toContain('getNoActiveProLicenseState'); expect(proLicensePlanSectionSource).toContain('getTrialEndedProLicenseNotice'); expect(proLicensePlanSectionSource).toContain('getInactiveProUpsellNotice'); + expect(proLicensePlanSectionSource).toContain('MonitoredSystemDefinitionDisclosure'); expect(proLicensePlanSectionSource).toContain('trialStartTitle'); expect(proLicensePlanSectionSource).toContain('trialStartIdleActionLabel'); expect(proLicensePlanSectionSource).not.toContain( diff --git a/frontend-modern/src/components/Settings/selfHostedBillingPresentation.ts b/frontend-modern/src/components/Settings/selfHostedBillingPresentation.ts index 6a8455be3f..d923127d6a 100644 --- a/frontend-modern/src/components/Settings/selfHostedBillingPresentation.ts +++ b/frontend-modern/src/components/Settings/selfHostedBillingPresentation.ts @@ -56,7 +56,7 @@ export const SELF_HOSTED_PRO_BILLING_PRESENTATION: SelfHostedProBillingPresentat 'Pulse waits for the session presentation policy before showing license, billing, or usage details.', monitoredSystemUpgradeArrivalTitle: 'Need a higher monitored-system cap?', monitoredSystemUpgradeArrivalBody: - 'Open Pulse Account to compare self-hosted plans, complete checkout, and return here with Pulse Pro activated automatically.', + 'Pulse counts top-level monitored systems such as Docker hosts, Kubernetes clusters, Proxmox nodes, standalone hosts, and TrueNAS systems. Compare self-hosted plans in Pulse Account and return here with Pulse Pro activated automatically.', monitoredSystemUpgradeArrivalActionLabel: 'Compare plans', purchaseActivatedUsageActionLabel: 'Review usage', purchaseCancelledActionLabel: 'Compare plans', diff --git a/frontend-modern/src/utils/__tests__/licensePresentation.test.ts b/frontend-modern/src/utils/__tests__/licensePresentation.test.ts index 1797d81fb3..0738b90c3c 100644 --- a/frontend-modern/src/utils/__tests__/licensePresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/licensePresentation.test.ts @@ -87,7 +87,7 @@ describe('licensePresentation', () => { 'Pulse waits for the session presentation policy before showing license, billing, or usage details.', monitoredSystemUpgradeArrivalTitle: 'Need a higher monitored-system cap?', monitoredSystemUpgradeArrivalBody: - 'Open Pulse Account to compare self-hosted plans, complete checkout, and return here with Pulse Pro activated automatically.', + 'Pulse counts top-level monitored systems such as Docker hosts, Kubernetes clusters, Proxmox nodes, standalone hosts, and TrueNAS systems. Compare self-hosted plans in Pulse Account and return here with Pulse Pro activated automatically.', monitoredSystemUpgradeArrivalActionLabel: 'Compare plans', purchaseActivatedUsageActionLabel: 'Review usage', purchaseCancelledActionLabel: 'Compare plans', diff --git a/tests/integration/tests/55-self-hosted-upgrade-return.spec.ts b/tests/integration/tests/55-self-hosted-upgrade-return.spec.ts index b3a6b28837..ab49bc7d31 100644 --- a/tests/integration/tests/55-self-hosted-upgrade-return.spec.ts +++ b/tests/integration/tests/55-self-hosted-upgrade-return.spec.ts @@ -373,6 +373,17 @@ async function openMonitoredSystemUpgradeArrival(page: Page) { "aria-selected", "true", ); + await expect( + page.getByText( + "Pulse counts top-level monitored systems such as Docker hosts, Kubernetes clusters, Proxmox nodes, standalone hosts, and TrueNAS systems. Compare self-hosted plans in Pulse Account and return here with Pulse Pro activated automatically.", + ), + ).toBeVisible(); + await expect(page.getByRole("button", { name: "Hide counting rules" })).toBeVisible(); + await expect( + page.getByText( + "A monitored system is a top-level monitored root such as a Docker host, Kubernetes cluster, Proxmox node, standalone host, or TrueNAS system. Each root counts once no matter how Pulse collects it. Child resources like VMs, containers, pods, disks, backups, and services underneath that root are included.", + ), + ).toBeVisible(); } test.describe("Self-hosted upgrade return flow", () => {