mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-08 18:21:55 +00:00
Share Pulse Pro referral copy across settings surfaces
This commit is contained in:
parent
fe7e47bc11
commit
7d032140a7
9 changed files with 45 additions and 14 deletions
|
|
@ -260,12 +260,6 @@ before any API-only token fallback or optional-auth anonymous fallback so
|
|||
operators can mint relay-mobile credentials and continue onboarding from the
|
||||
hosted runtime itself even after that tenant has already minted managed API
|
||||
tokens.
|
||||
That same lifecycle-adjacent hosted setup path must also survive legacy tenant
|
||||
runtime env drift. When Pulse Account hands an operator into a hosted workspace,
|
||||
`internal/api/cloud_handoff_handlers.go` must still recover the canonical
|
||||
tenant context from hosted runtime state if `PULSE_TENANT_ID` is missing, so
|
||||
lifecycle entry into onboarding, setup, and mobile-pairing surfaces does not
|
||||
die before the first authenticated page load.
|
||||
That same lifecycle-adjacent hosted setup path also depends on AI bootstrap
|
||||
staying canonical before the first settings write. Hosted operators may land
|
||||
in Chat, Patrol-backed setup hints, or AI-dependent remediation surfaces
|
||||
|
|
@ -333,6 +327,11 @@ and `frontend-modern/src/utils/proxmoxSettingsPresentation.ts`, so endpoint
|
|||
reachability state, discovery-prefill defaults, and variant copy stay on the
|
||||
same governed lifecycle surface instead of drifting into card-local strings or
|
||||
prefill assembly.
|
||||
When that infrastructure workspace needs to redirect operators to the Pulse Pro
|
||||
surface for billing, monitored-system limits, or license status, it must
|
||||
consume the shared referral copy from
|
||||
`frontend-modern/src/utils/licensePresentation.ts` instead of carrying
|
||||
workspace-local commercial guidance.
|
||||
That canonical /api/auto-register behavior now also includes hostname/IP continuity:
|
||||
reruns that arrive through a different canonical host form must reuse the same
|
||||
Pulse-managed node record and token instead of forking duplicate fleet entries.
|
||||
|
|
|
|||
|
|
@ -489,6 +489,12 @@ The same title should also feed the `system-billing` settings navigation item,
|
|||
and the same title and description should also feed the `system-billing` route
|
||||
header metadata so the nav, shell, and route header do not narrate the same
|
||||
commercial surface differently.
|
||||
That same shared presentation owner also carries the canonical cross-surface
|
||||
referral copy used outside the billing shell itself. When infrastructure or
|
||||
other adjacent settings surfaces need to point operators toward Pulse Pro for
|
||||
billing, monitored-system limits, or license status, they must consume the
|
||||
shared referral strings from `frontend-modern/src/utils/licensePresentation.ts`
|
||||
instead of drafting route-local commercial guidance.
|
||||
Paid Pulse Pro v5 grandfathering is now part of that same canonical boundary:
|
||||
when a recurring v5 customer migrates into v6, billing persistence,
|
||||
entitlement evaluation, renewal handling, and Pro-license presentation must
|
||||
|
|
|
|||
|
|
@ -157,7 +157,10 @@ work extends shared components instead of creating new local variants.
|
|||
5. When a settings route header and a top-level settings shell describe the same
|
||||
commercial surface, keep them on the same shared presentation owner instead
|
||||
of allowing route metadata in `settingsHeaderMeta.ts` or labels in
|
||||
`settingsNavCatalog.ts` to drift into independent title or description copy.
|
||||
`settingsNavCatalog.ts` to drift into independent title or description copy,
|
||||
and keep adjacent settings-shell referrals such as
|
||||
`InfrastructureWorkspace.tsx` on that same shared owner instead of
|
||||
reintroducing local “go to Pulse Pro” variants.
|
||||
|
||||
## Current State
|
||||
|
||||
|
|
@ -1255,6 +1258,13 @@ navigation label plus header title and description must reuse
|
|||
`SELF_HOSTED_PRO_BILLING_PRESENTATION.shellTitle` and
|
||||
`SELF_HOSTED_PRO_BILLING_PRESENTATION.shellDescription` so the route header and
|
||||
the billing shell do not narrate the same commercial surface differently.
|
||||
That same settings-shell framing boundary also covers adjacent top-level
|
||||
settings references to the self-hosted commercial surface. When
|
||||
`InfrastructureWorkspace.tsx` or other settings-shell surfaces point operators
|
||||
toward Pulse Pro for billing, monitored-system limits, or license status, they
|
||||
must reuse the shared referral copy from
|
||||
`SELF_HOSTED_PRO_BILLING_PRESENTATION` rather than drafting local “go there
|
||||
for billing” variants.
|
||||
`frontend-modern/src/components/Settings/NetworkSettingsPanel.tsx` is now a
|
||||
shell only. `frontend-modern/src/components/Settings/NetworkDiscoverySection.tsx`
|
||||
owns discovery controls and shared subnet presets, while
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { Component, Match, Switch, createMemo } from 'solid-js';
|
|||
import { useLocation, useNavigate } from '@solidjs/router';
|
||||
import { Card } from '@/components/shared/Card';
|
||||
import { Subtabs } from '@/components/shared/Subtabs';
|
||||
import { SELF_HOSTED_PRO_BILLING_PRESENTATION } from '@/utils/licensePresentation';
|
||||
import { InfrastructureInstallPanel } from './InfrastructureInstallPanel';
|
||||
import { InfrastructureReportingPanel } from './InfrastructureReportingPanel';
|
||||
import { ProxmoxSettingsPanel } from './ProxmoxSettingsPanel';
|
||||
|
|
@ -33,8 +34,7 @@ export const InfrastructureWorkspace: Component<InfrastructureWorkspaceProps> =
|
|||
connections, and control which infrastructure surfaces are actively reporting.
|
||||
</p>
|
||||
<p class="text-sm text-muted">
|
||||
Billing, monitored-system limits, and Pulse Pro license status live in Pulse Pro,
|
||||
not here.
|
||||
{SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureWorkspaceReferral}
|
||||
</p>
|
||||
</div>
|
||||
</Card>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { cleanup, fireEvent, render, screen } from '@solidjs/testing-library';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { SELF_HOSTED_PRO_BILLING_PRESENTATION } from '@/utils/licensePresentation';
|
||||
import { InfrastructureWorkspace } from '../InfrastructureWorkspace';
|
||||
|
||||
let mockPathname = '/settings';
|
||||
|
|
@ -57,9 +58,7 @@ describe('InfrastructureWorkspace', () => {
|
|||
expect(tablist).toBeInTheDocument();
|
||||
expect(screen.getByText('Infrastructure operations')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
'Billing, monitored-system limits, and Pulse Pro license status live in Pulse Pro, not here.',
|
||||
),
|
||||
screen.getByText(SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureWorkspaceReferral),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole('tab', { name: 'Install on a host' })).toHaveAttribute(
|
||||
'aria-selected',
|
||||
|
|
|
|||
|
|
@ -548,6 +548,13 @@ describe('Settings architecture guardrails', () => {
|
|||
expect(proLicensePanelSource).not.toContain('description="Manage self-hosted billing');
|
||||
expect(proLicensePanelSource).not.toContain('title="Plan"');
|
||||
expect(proLicensePanelSource).not.toContain('title="Usage"');
|
||||
expect(infrastructureWorkspaceSource).toContain('@/utils/licensePresentation');
|
||||
expect(infrastructureWorkspaceSource).toContain(
|
||||
'SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureWorkspaceReferral',
|
||||
);
|
||||
expect(infrastructureWorkspaceSource).not.toContain(
|
||||
'Billing, monitored-system limits, and Pulse Pro license status live in Pulse Pro, not here.',
|
||||
);
|
||||
expect(proLicensePlanSectionSource).toContain('CommercialStatGrid');
|
||||
expect(proLicensePlanSectionSource).toContain('getLicenseStatusLoadingState');
|
||||
expect(monitoredSystemPresentationSource).toContain(
|
||||
|
|
@ -1266,7 +1273,9 @@ describe('Settings architecture guardrails', () => {
|
|||
expect(SETTINGS_HEADER_META['infrastructure-operations'].description).toContain(
|
||||
'actively reporting',
|
||||
);
|
||||
expect(SETTINGS_HEADER_META['infrastructure-operations'].description).toContain('Pulse Pro');
|
||||
expect(SETTINGS_HEADER_META['infrastructure-operations'].description).toBe(
|
||||
`Bring infrastructure into Pulse, manage direct Proxmox connections, and control which systems are actively reporting. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps billing-related shell framing on monitored-system commercial terms', () => {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export const SETTINGS_HEADER_META: SettingsHeaderMetaMap = {
|
|||
'infrastructure-operations': {
|
||||
title: 'Infrastructure Operations',
|
||||
description:
|
||||
'Bring infrastructure into Pulse, manage direct Proxmox connections, and control which systems are actively reporting. Billing and monitored-system limits live in Pulse Pro.',
|
||||
`Bring infrastructure into Pulse, manage direct Proxmox connections, and control which systems are actively reporting. ${SELF_HOSTED_PRO_BILLING_PRESENTATION.infrastructureRouteReferral}`,
|
||||
},
|
||||
'system-general': {
|
||||
title: 'General',
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ describe('licensePresentation', () => {
|
|||
shellTitle: 'Pulse Pro',
|
||||
shellDescription:
|
||||
'Manage self-hosted billing, monitored-system limits, and Pulse Pro license status.',
|
||||
infrastructureRouteReferral: 'Billing and monitored-system limits live in Pulse Pro.',
|
||||
infrastructureWorkspaceReferral:
|
||||
'Billing, monitored-system limits, and Pulse Pro license status live in Pulse Pro, not here.',
|
||||
refreshLabel: 'Refresh',
|
||||
planSectionTitle: 'Plan',
|
||||
planSectionDescription:
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ export interface SelfHostedActivationPresentation {
|
|||
export interface SelfHostedProBillingPresentation {
|
||||
shellTitle: string;
|
||||
shellDescription: string;
|
||||
infrastructureRouteReferral: string;
|
||||
infrastructureWorkspaceReferral: string;
|
||||
refreshLabel: string;
|
||||
planSectionTitle: string;
|
||||
planSectionDescription: string;
|
||||
|
|
@ -375,6 +377,9 @@ export const SELF_HOSTED_PRO_BILLING_PRESENTATION: SelfHostedProBillingPresentat
|
|||
shellTitle: 'Pulse Pro',
|
||||
shellDescription:
|
||||
'Manage self-hosted billing, monitored-system limits, and Pulse Pro license status.',
|
||||
infrastructureRouteReferral: 'Billing and monitored-system limits live in Pulse Pro.',
|
||||
infrastructureWorkspaceReferral:
|
||||
'Billing, monitored-system limits, and Pulse Pro license status live in Pulse Pro, not here.',
|
||||
refreshLabel: 'Refresh',
|
||||
planSectionTitle: 'Plan',
|
||||
planSectionDescription:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue