Explain monitored-system counting on the plan surface

This commit is contained in:
rcourtman 2026-04-15 10:57:17 +01:00
parent 0080108fa8
commit 41ef7b2830
6 changed files with 50 additions and 2 deletions

View file

@ -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

View file

@ -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<ProLicensePlanSectionProps> = (pro
</UpgradeLink>
</div>
</Show>
<div class="mb-4 rounded-md border border-border bg-surface-alt p-3">
<MonitoredSystemDefinitionDisclosure
showSummary
defaultOpen={props.showMonitoredSystemUpgradeArrival}
/>
</div>
<Show when={props.trialActivationNotice}>
{(notice) => (
<div class={`mb-4 rounded-md border p-3 text-sm ${notice().tone}`}>

View file

@ -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(

View file

@ -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',

View file

@ -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',

View file

@ -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", () => {