Split monitored system limit warning banner owners

This commit is contained in:
rcourtman
2026-03-23 08:56:44 +00:00
parent 3199455bc4
commit 91528fdb1c
7 changed files with 336 additions and 120 deletions
@@ -597,6 +597,15 @@ That banner boundary now also owns the canonical monitored-system naming
surface directly: the shared warning component path and exported symbol are
`MonitoredSystemLimitWarningBanner`, and future work may not reintroduce an
agent-era banner filename or component name as the primary primitive.
That shared monitored-system warning banner now also follows the shell/runtime/model
owner split. `frontend-modern/src/components/shared/MonitoredSystemLimitWarningBanner.tsx`
stays the render shell, `frontend-modern/src/components/shared/useMonitoredSystemLimitWarningBannerState.ts`
owns entitlement load, warning metric emission, migration/upgrade click tracking,
and upgrade-link runtime, and
`frontend-modern/src/components/shared/monitoredSystemLimitWarningBannerModel.ts`
owns monitored-system summary, migration copy, overflow summary, and tone/text-class
policy. Future warning-banner work should extend those owners instead of pushing
entitlement orchestration, tracking, or naming math back into the shared shell.
First-session educational surfaces must also stay brief, flat, and model-led.
When Pulse needs to teach a user how a flow works, the primary on-screen
guidance should collapse to a few short descriptions of the real product
@@ -1,143 +1,55 @@
import { Component, Show, createEffect, createMemo } from 'solid-js';
import { Component, Show } from 'solid-js';
import {
entitlements,
getLimit,
getUpgradeActionUrlOrFallback,
hasMigrationGap,
legacyConnections,
} from '@/stores/license';
import {
trackUpgradeClicked,
trackUpgradeMetricEvent,
UPGRADE_METRIC_EVENTS,
} from '@/utils/upgradeMetrics';
MONITORED_SYSTEM_LIMIT_BILLING_HREF,
MONITORED_SYSTEM_LIMIT_INSTALL_COLLECTORS_HREF,
MONITORED_SYSTEM_LIMIT_INSTALL_COLLECTORS_LABEL,
MONITORED_SYSTEM_LIMIT_LEARN_MORE_LABEL,
MONITORED_SYSTEM_LIMIT_UPGRADE_LABEL,
} from './monitoredSystemLimitWarningBannerModel';
import { useMonitoredSystemLimitWarningBannerState } from './useMonitoredSystemLimitWarningBannerState';
export const MonitoredSystemLimitWarningBanner: Component = () => {
// No onMount load — TrialBanner (mounted above) already calls loadLicenseStatus().
const monitoredSystemLimit = createMemo(() => getLimit('max_monitored_systems'));
const isUrgent = createMemo(() => {
const state = monitoredSystemLimit()?.state;
return state === 'warning' || state === 'enforced';
});
const migrationGap = createMemo(() => hasMigrationGap());
const migrationCounts = createMemo(() => legacyConnections());
const legacyConnectionTotal = createMemo(() => {
const counts = migrationCounts();
return counts.proxmox_nodes + counts.docker_hosts + counts.kubernetes_clusters;
});
const showBanner = createMemo(() => Boolean(monitoredSystemLimit()) && isUrgent());
const monitoredSystemSummary = createMemo(() => {
const limit = monitoredSystemLimit();
if (!limit) return '';
return `Monitored systems: ${limit.current}/${limit.limit}`;
});
const legacyBreakdown = createMemo(() => {
const counts = migrationCounts();
const parts: string[] = [];
if (counts.proxmox_nodes > 0) {
parts.push(
`${counts.proxmox_nodes} Proxmox ${counts.proxmox_nodes === 1 ? 'node' : 'nodes'}`,
);
}
if (counts.docker_hosts > 0) {
parts.push(`${counts.docker_hosts} Docker ${counts.docker_hosts === 1 ? 'host' : 'hosts'}`);
}
if (counts.kubernetes_clusters > 0) {
parts.push(
`${counts.kubernetes_clusters} Kubernetes ${counts.kubernetes_clusters === 1 ? 'cluster' : 'clusters'}`,
);
}
return parts.join(', ');
});
const migrationMessage = createMemo(() => {
const total = legacyConnectionTotal();
if (total <= 0) return '';
const noun = total === 1 ? 'resource' : 'resources';
const breakdown = legacyBreakdown();
return `You also have ${total} ${noun} connected via API or legacy collectors${breakdown ? ` (${breakdown})` : ''} that count once toward your monitored-system cap when the same top-level system is discovered canonically.`;
});
const overflowDaysRemaining = createMemo(() => entitlements()?.overflow_days_remaining);
const overflowSummary = createMemo(() => {
const days = overflowDaysRemaining();
if (!days) return '';
return `Includes 1 temporary onboarding slot (${days}d remaining)`;
});
// Emit limit_warning_shown once when the banner transitions to warning/enforced.
// Uses previous-state tracking to avoid re-emitting on every reactive update.
let prevUrgent = false;
createEffect(() => {
const urgent = isUrgent();
const limit = monitoredSystemLimit();
if (urgent && !prevUrgent && limit) {
trackUpgradeMetricEvent({
type: UPGRADE_METRIC_EVENTS.LIMIT_WARNING_SHOWN,
surface: 'monitored_system_limit_banner',
limit_key: 'max_monitored_systems',
current_value: limit.current,
limit_value: limit.limit,
});
}
prevUrgent = !!urgent;
});
const state = useMonitoredSystemLimitWarningBannerState();
return (
<Show when={showBanner()}>
<Show when={state.showBanner()}>
<div
class={`mb-2 rounded-md border px-3 py-2 text-sm ${
isUrgent()
? 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-900 dark:text-amber-100'
: 'border-sky-200 bg-sky-50 text-sky-950 dark:border-sky-900 dark:bg-sky-950 dark:text-sky-100'
}`}
class={`mb-2 rounded-md border px-3 py-2 text-sm ${state.toneClass()}`}
role="status"
aria-live="polite"
>
<div class="flex flex-wrap items-center gap-x-3 gap-y-1">
<span class={isUrgent() ? 'font-medium' : ''}>{monitoredSystemSummary()}</span>
<Show when={overflowSummary()}>
<span class="text-xs opacity-80">{overflowSummary()}</span>
<span class={state.isUrgent() ? 'font-medium' : ''}>{state.monitoredSystemSummary()}</span>
<Show when={state.overflowSummary()}>
<span class="text-xs opacity-80">{state.overflowSummary()}</span>
</Show>
<Show when={migrationGap()}>
<span
class={`text-xs ${isUrgent() ? 'text-amber-800 dark:text-amber-200' : 'text-sky-800 dark:text-sky-200'}`}
>
{migrationMessage()}
</span>
<Show when={state.migrationGap()}>
<span class={`text-xs ${state.migrationTextClass()}`}>{state.migrationMessage()}</span>
</Show>
<a
class="text-xs font-medium underline underline-offset-2 hover:opacity-90"
href="/settings/system/billing"
href={MONITORED_SYSTEM_LIMIT_BILLING_HREF}
>
Learn more
{MONITORED_SYSTEM_LIMIT_LEARN_MORE_LABEL}
</a>
<Show when={migrationGap()}>
<Show when={state.migrationGap()}>
<a
class="text-xs font-medium underline underline-offset-2 hover:opacity-90"
href="/settings"
onClick={() =>
trackUpgradeClicked(
'monitored_system_limit_banner_install_v6_collectors',
'max_monitored_systems',
)
}
href={MONITORED_SYSTEM_LIMIT_INSTALL_COLLECTORS_HREF}
onClick={state.handleInstallCollectorsClick}
>
Install v6 collectors
{MONITORED_SYSTEM_LIMIT_INSTALL_COLLECTORS_LABEL}
</a>
</Show>
<Show when={isUrgent()}>
<Show when={state.isUrgent()}>
<a
class="text-xs font-semibold underline underline-offset-2 hover:opacity-90"
href={getUpgradeActionUrlOrFallback('max_monitored_systems')}
href={state.upgradeHref()}
target="_blank"
rel="noreferrer"
onClick={() =>
trackUpgradeClicked('monitored_system_limit_banner_upgrade', 'max_monitored_systems')
}
onClick={state.handleUpgradeClick}
>
Upgrade to add more
{MONITORED_SYSTEM_LIMIT_UPGRADE_LABEL}
</a>
</Show>
</div>
@@ -47,6 +47,7 @@ import infrastructureSelectorModelSource from '@/components/shared/infrastructur
import infrastructureSummaryTableModelSource from '@/components/shared/infrastructureSummaryTableModel.ts?raw';
import infrastructureSummaryTableStateSource from '@/components/shared/useInfrastructureSummaryTableState.ts?raw';
import monitoredSystemLimitWarningBannerSource from '@/components/shared/MonitoredSystemLimitWarningBanner.tsx?raw';
import monitoredSystemLimitWarningBannerModelSource from '@/components/shared/monitoredSystemLimitWarningBannerModel.ts?raw';
import selectionCardGroupSource from '@/components/shared/SelectionCardGroup.tsx?raw';
import tagBadgesSource from '@/components/shared/TagBadges.tsx?raw';
import commandPaletteStateSource from '@/components/shared/useCommandPaletteState.ts?raw';
@@ -68,6 +69,7 @@ import searchTipsPopoverStateSource from '@/components/shared/useSearchTipsPopov
import tooltipStateSource from '@/components/shared/useTooltipState.ts?raw';
import trialBannerStateSource from '@/components/shared/useTrialBannerState.ts?raw';
import interactiveSparklineStateSource from '@/components/shared/useInteractiveSparklineState.ts?raw';
import monitoredSystemLimitWarningBannerStateSource from '@/components/shared/useMonitoredSystemLimitWarningBannerState.ts?raw';
import webInterfaceUrlFieldSource from '@/components/shared/WebInterfaceUrlField.tsx?raw';
import webInterfaceUrlFieldModelSource from '@/components/shared/webInterfaceUrlFieldModel.ts?raw';
import webInterfaceUrlFieldStateSource from '@/components/shared/useWebInterfaceUrlFieldState.ts?raw';
@@ -218,18 +220,55 @@ describe('shared primitive guardrails', () => {
});
it('keeps shared fleet limit banner copy on the monitored-system commercial term', () => {
expect(monitoredSystemLimitWarningBannerSource).toContain('Monitored systems:');
expect(monitoredSystemLimitWarningBannerSource).toContain('monitored-system cap');
expect(monitoredSystemLimitWarningBannerSource).toContain('Install v6 collectors');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('v6 Unified Agents:');
expect(monitoredSystemLimitWarningBannerSource).not.toContain(
expect(monitoredSystemLimitWarningBannerModelSource).toContain('Monitored systems:');
expect(monitoredSystemLimitWarningBannerModelSource).toContain('monitored-system cap');
expect(monitoredSystemLimitWarningBannerModelSource).toContain('Install v6 collectors');
expect(monitoredSystemLimitWarningBannerModelSource).not.toContain('v6 Unified Agents:');
expect(monitoredSystemLimitWarningBannerModelSource).not.toContain(
'do not count toward Unified Agents.',
);
expect(monitoredSystemLimitWarningBannerSource).not.toContain(
expect(monitoredSystemLimitWarningBannerModelSource).not.toContain(
'Install v6 Unified Agents',
);
});
it('keeps monitored system limit warning banner on shell, runtime, and model owners', () => {
expect(monitoredSystemLimitWarningBannerSource).toContain(
'useMonitoredSystemLimitWarningBannerState',
);
expect(monitoredSystemLimitWarningBannerSource).toContain(
'MONITORED_SYSTEM_LIMIT_LEARN_MORE_LABEL',
);
expect(monitoredSystemLimitWarningBannerSource).not.toContain('createEffect');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('createMemo');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('loadLicenseStatus');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('trackUpgradeMetricEvent');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('legacyConnections()');
expect(monitoredSystemLimitWarningBannerStateSource).toContain(
'export function useMonitoredSystemLimitWarningBannerState',
);
expect(monitoredSystemLimitWarningBannerStateSource).toContain('createEffect');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('createMemo');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('loadLicenseStatus');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('trackUpgradeMetricEvent');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('legacyConnections');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('handleUpgradeClick');
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'getMonitoredSystemMigrationMessage',
);
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'getMonitoredSystemBannerToneClass',
);
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'MONITORED_SYSTEM_LIMIT_UPGRADE_LABEL',
);
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'MONITORED_SYSTEM_LIMIT_INSTALL_COLLECTORS_LABEL',
);
});
it('keeps shared tag badges in the shared primitive boundary', () => {
expect(tagBadgesSource).toContain("from '@/components/shared/Tooltip'");
expect(guestRowSource).toContain("from '@/components/shared/TagBadges'");
@@ -1,5 +1,8 @@
import { cleanup, render, screen } from '@solidjs/testing-library';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import monitoredSystemLimitWarningBannerSource from '@/components/shared/MonitoredSystemLimitWarningBanner.tsx?raw';
import monitoredSystemLimitWarningBannerModelSource from '@/components/shared/monitoredSystemLimitWarningBannerModel.ts?raw';
import monitoredSystemLimitWarningBannerStateSource from '@/components/shared/useMonitoredSystemLimitWarningBannerState.ts?raw';
type MockEntitlements = {
overflow_days_remaining?: number;
@@ -26,6 +29,7 @@ const mockLegacyConnections = vi.hoisted(() =>
);
const mockTrackUpgradeMetricEvent = vi.hoisted(() => vi.fn());
const mockTrackUpgradeClicked = vi.hoisted(() => vi.fn());
const mockLoadLicenseStatus = vi.hoisted(() => vi.fn());
vi.mock('@/stores/license', () => ({
entitlements: mockEntitlements,
@@ -33,6 +37,7 @@ vi.mock('@/stores/license', () => ({
getUpgradeActionUrlOrFallback: vi.fn(() => '/pricing?feature=max_monitored_systems'),
hasMigrationGap: mockHasMigrationGap,
legacyConnections: mockLegacyConnections,
loadLicenseStatus: (...args: unknown[]) => mockLoadLicenseStatus(...args),
}));
vi.mock('@/utils/upgradeMetrics', () => ({
@@ -54,6 +59,8 @@ describe('MonitoredSystemLimitWarningBanner', () => {
docker_hosts: 0,
kubernetes_clusters: 0,
});
mockLoadLicenseStatus.mockReset();
mockLoadLicenseStatus.mockResolvedValue(undefined);
});
afterEach(() => {
@@ -61,10 +68,48 @@ describe('MonitoredSystemLimitWarningBanner', () => {
vi.clearAllMocks();
});
it('keeps monitored system limit warning banner on shell, runtime, and model owners', () => {
expect(monitoredSystemLimitWarningBannerSource).toContain(
'useMonitoredSystemLimitWarningBannerState',
);
expect(monitoredSystemLimitWarningBannerSource).toContain(
'MONITORED_SYSTEM_LIMIT_LEARN_MORE_LABEL',
);
expect(monitoredSystemLimitWarningBannerSource).not.toContain('createEffect');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('createMemo');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('loadLicenseStatus');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('trackUpgradeMetricEvent');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('legacyConnections()');
expect(monitoredSystemLimitWarningBannerStateSource).toContain(
'export function useMonitoredSystemLimitWarningBannerState',
);
expect(monitoredSystemLimitWarningBannerStateSource).toContain('createEffect');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('createMemo');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('loadLicenseStatus');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('trackUpgradeMetricEvent');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('legacyConnections');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('handleUpgradeClick');
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'getMonitoredSystemMigrationMessage',
);
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'getMonitoredSystemBannerToneClass',
);
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'MONITORED_SYSTEM_LIMIT_UPGRADE_LABEL',
);
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'MONITORED_SYSTEM_LIMIT_INSTALL_COLLECTORS_LABEL',
);
});
it('stays hidden for non-urgent pure v6 installs', async () => {
const mod = await import('../MonitoredSystemLimitWarningBanner');
render(() => <mod.MonitoredSystemLimitWarningBanner />);
expect(mockLoadLicenseStatus).toHaveBeenCalled();
expect(screen.queryByText(/Monitored systems:/i)).not.toBeInTheDocument();
});
@@ -0,0 +1,86 @@
type LimitState = {
current: number;
limit: number;
state?: string;
};
type LegacyConnectionCounts = {
proxmox_nodes: number;
docker_hosts: number;
kubernetes_clusters: number;
};
export const MONITORED_SYSTEM_LIMIT_KEY = 'max_monitored_systems';
export const MONITORED_SYSTEM_LIMIT_BILLING_HREF = '/settings/system/billing';
export const MONITORED_SYSTEM_LIMIT_INSTALL_COLLECTORS_HREF = '/settings';
export const MONITORED_SYSTEM_LIMIT_LEARN_MORE_LABEL = 'Learn more';
export const MONITORED_SYSTEM_LIMIT_INSTALL_COLLECTORS_LABEL = 'Install v6 collectors';
export const MONITORED_SYSTEM_LIMIT_UPGRADE_LABEL = 'Upgrade to add more';
export function isMonitoredSystemLimitUrgent(limit: LimitState | undefined): boolean {
const state = limit?.state;
return state === 'warning' || state === 'enforced';
}
export function shouldShowMonitoredSystemLimitBanner(limit: LimitState | undefined): boolean {
return Boolean(limit) && isMonitoredSystemLimitUrgent(limit);
}
export function getMonitoredSystemSummary(limit: LimitState | undefined): string {
if (!limit) return '';
return `Monitored systems: ${limit.current}/${limit.limit}`;
}
export function getMonitoredSystemLegacyConnectionTotal(counts: LegacyConnectionCounts): number {
return counts.proxmox_nodes + counts.docker_hosts + counts.kubernetes_clusters;
}
export function getMonitoredSystemLegacyBreakdown(counts: LegacyConnectionCounts): string {
const parts: string[] = [];
if (counts.proxmox_nodes > 0) {
parts.push(
`${counts.proxmox_nodes} Proxmox ${counts.proxmox_nodes === 1 ? 'node' : 'nodes'}`,
);
}
if (counts.docker_hosts > 0) {
parts.push(`${counts.docker_hosts} Docker ${counts.docker_hosts === 1 ? 'host' : 'hosts'}`);
}
if (counts.kubernetes_clusters > 0) {
parts.push(
`${counts.kubernetes_clusters} Kubernetes ${
counts.kubernetes_clusters === 1 ? 'cluster' : 'clusters'
}`,
);
}
return parts.join(', ');
}
export function getMonitoredSystemMigrationMessage(counts: LegacyConnectionCounts): string {
const total = getMonitoredSystemLegacyConnectionTotal(counts);
if (total <= 0) return '';
const noun = total === 1 ? 'resource' : 'resources';
const breakdown = getMonitoredSystemLegacyBreakdown(counts);
return `You also have ${total} ${noun} connected via API or legacy collectors${
breakdown ? ` (${breakdown})` : ''
} that count once toward your monitored-system cap when the same top-level system is discovered canonically.`;
}
export function getMonitoredSystemOverflowSummary(daysRemaining: number | undefined): string {
if (!daysRemaining) return '';
return `Includes 1 temporary onboarding slot (${daysRemaining}d remaining)`;
}
export function getMonitoredSystemBannerToneClass(isUrgent: boolean): string {
return isUrgent
? 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-900 dark:text-amber-100'
: 'border-sky-200 bg-sky-50 text-sky-950 dark:border-sky-900 dark:bg-sky-950 dark:text-sky-100';
}
export function getMonitoredSystemMigrationTextClass(isUrgent: boolean): string {
return isUrgent
? 'text-amber-800 dark:text-amber-200'
: 'text-sky-800 dark:text-sky-200';
}
@@ -0,0 +1,93 @@
import { createEffect, createMemo, onMount } from 'solid-js';
import {
entitlements,
getLimit,
getUpgradeActionUrlOrFallback,
hasMigrationGap,
legacyConnections,
loadLicenseStatus,
} from '@/stores/license';
import {
trackUpgradeClicked,
trackUpgradeMetricEvent,
UPGRADE_METRIC_EVENTS,
} from '@/utils/upgradeMetrics';
import {
getMonitoredSystemBannerToneClass,
getMonitoredSystemMigrationMessage,
getMonitoredSystemMigrationTextClass,
getMonitoredSystemOverflowSummary,
getMonitoredSystemSummary,
isMonitoredSystemLimitUrgent,
MONITORED_SYSTEM_LIMIT_KEY,
shouldShowMonitoredSystemLimitBanner,
} from './monitoredSystemLimitWarningBannerModel';
export function useMonitoredSystemLimitWarningBannerState() {
onMount(() => {
void loadLicenseStatus();
});
const monitoredSystemLimit = createMemo(() => getLimit(MONITORED_SYSTEM_LIMIT_KEY));
const isUrgent = createMemo(() => isMonitoredSystemLimitUrgent(monitoredSystemLimit()));
const showBanner = createMemo(() => shouldShowMonitoredSystemLimitBanner(monitoredSystemLimit()));
const migrationGap = createMemo(() => hasMigrationGap());
const migrationCounts = createMemo(() => legacyConnections());
const monitoredSystemSummary = createMemo(() =>
getMonitoredSystemSummary(monitoredSystemLimit()),
);
const migrationMessage = createMemo(() =>
getMonitoredSystemMigrationMessage(migrationCounts()),
);
const overflowSummary = createMemo(() =>
getMonitoredSystemOverflowSummary(entitlements()?.overflow_days_remaining),
);
const toneClass = createMemo(() => getMonitoredSystemBannerToneClass(isUrgent()));
const migrationTextClass = createMemo(() =>
getMonitoredSystemMigrationTextClass(isUrgent()),
);
const upgradeHref = createMemo(() =>
getUpgradeActionUrlOrFallback(MONITORED_SYSTEM_LIMIT_KEY),
);
let wasUrgent = false;
createEffect(() => {
const urgent = isUrgent();
const limit = monitoredSystemLimit();
if (urgent && !wasUrgent && limit) {
trackUpgradeMetricEvent({
type: UPGRADE_METRIC_EVENTS.LIMIT_WARNING_SHOWN,
surface: 'monitored_system_limit_banner',
limit_key: MONITORED_SYSTEM_LIMIT_KEY,
current_value: limit.current,
limit_value: limit.limit,
});
}
wasUrgent = urgent;
});
const handleInstallCollectorsClick = () => {
trackUpgradeClicked(
'monitored_system_limit_banner_install_v6_collectors',
MONITORED_SYSTEM_LIMIT_KEY,
);
};
const handleUpgradeClick = () => {
trackUpgradeClicked('monitored_system_limit_banner_upgrade', MONITORED_SYSTEM_LIMIT_KEY);
};
return {
handleInstallCollectorsClick,
handleUpgradeClick,
isUrgent,
migrationGap,
migrationMessage,
migrationTextClass,
monitoredSystemSummary,
overflowSummary,
showBanner,
toneClass,
upgradeHref,
};
}
@@ -44,6 +44,8 @@ import tooltipSource from '@/components/shared/Tooltip.tsx?raw';
import tooltipModelSource from '@/components/shared/tooltipModel.ts?raw';
import trialBannerSource from '@/components/shared/TrialBanner.tsx?raw';
import trialBannerModelSource from '@/components/shared/trialBannerModel.ts?raw';
import monitoredSystemLimitWarningBannerSource from '@/components/shared/MonitoredSystemLimitWarningBanner.tsx?raw';
import monitoredSystemLimitWarningBannerModelSource from '@/components/shared/monitoredSystemLimitWarningBannerModel.ts?raw';
import infrastructureSummaryTableSource from '@/components/shared/InfrastructureSummaryTable.tsx?raw';
import infrastructureSummaryTableRowSource from '@/components/shared/InfrastructureSummaryTableRow.tsx?raw';
import interactiveSparklineSource from '@/components/shared/InteractiveSparkline.tsx?raw';
@@ -67,6 +69,7 @@ import searchTipsPopoverStateSource from '@/components/shared/useSearchTipsPopov
import tooltipStateSource from '@/components/shared/useTooltipState.ts?raw';
import trialBannerStateSource from '@/components/shared/useTrialBannerState.ts?raw';
import interactiveSparklineStateSource from '@/components/shared/useInteractiveSparklineState.ts?raw';
import monitoredSystemLimitWarningBannerStateSource from '@/components/shared/useMonitoredSystemLimitWarningBannerState.ts?raw';
import infrastructureSummaryTableStateSource from '@/components/shared/useInfrastructureSummaryTableState.ts?raw';
import resourceBadgePresentationSource from '@/utils/resourceBadgePresentation.ts?raw';
import workloadTypeBadgesSource from '@/components/shared/workloadTypeBadges.ts?raw';
@@ -2751,6 +2754,35 @@ describe('frontend resource type boundaries', () => {
expect(trialBannerModelSource).toContain('getTrialBannerToneClass');
expect(trialBannerModelSource).toContain('getTrialBannerStatusLabel');
expect(trialBannerModelSource).toContain('TRIAL_BANNER_UPGRADE_LABEL');
expect(monitoredSystemLimitWarningBannerSource).toContain(
'useMonitoredSystemLimitWarningBannerState',
);
expect(monitoredSystemLimitWarningBannerSource).toContain(
'MONITORED_SYSTEM_LIMIT_LEARN_MORE_LABEL',
);
expect(monitoredSystemLimitWarningBannerSource).not.toContain('createEffect');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('createMemo');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('loadLicenseStatus');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('trackUpgradeMetricEvent');
expect(monitoredSystemLimitWarningBannerSource).not.toContain('legacyConnections()');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('createEffect');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('createMemo');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('loadLicenseStatus');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('trackUpgradeMetricEvent');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('legacyConnections');
expect(monitoredSystemLimitWarningBannerStateSource).toContain('handleUpgradeClick');
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'getMonitoredSystemMigrationMessage',
);
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'getMonitoredSystemBannerToneClass',
);
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'MONITORED_SYSTEM_LIMIT_UPGRADE_LABEL',
);
expect(monitoredSystemLimitWarningBannerModelSource).toContain(
'MONITORED_SYSTEM_LIMIT_INSTALL_COLLECTORS_LABEL',
);
expect(whatsNewModalSource).toContain('useWhatsNewModalState');
expect(whatsNewModalSource).toContain('WHATS_NEW_FEATURE_CARDS');
expect(whatsNewModalSource).not.toContain('createLocalStorageBooleanSignal');