Remove 103 unused frontend exports

Dead-code sweep. Named exports flagged unused by ts-prune and confirmed
unreferenced by adversarial cross-file verification, removed via a TypeScript
compiler-API codemod (whole-declaration removal by name). tsc --noEmit over the
full project including all test files, and npm run lint (eslint + theme +
canonical-platform audits), both pass.

54 candidates deferred for safety: 1 false positive caught by the type-check
(WizardState is imported by SetupCompletionPanel.tsx), ~20 files whose export
removal orphans secondary imports/helpers (needs a follow-up cascading pass),
and 2 multi-declarator statements.
This commit is contained in:
rcourtman 2026-06-03 12:37:38 +01:00
parent faefe6edc8
commit 62cff03210
60 changed files with 7 additions and 527 deletions

View file

@ -556,20 +556,6 @@ export interface StepResult {
run_at: string;
}
export interface RemediationExecution {
id: string;
plan_id: string;
status: 'pending' | 'approved' | 'running' | 'completed' | 'failed' | 'rolled_back';
approved_by?: string;
approved_at?: string;
started_at?: string;
completed_at?: string;
current_step: number;
step_results?: StepResult[];
error?: string;
rollback_error?: string;
}
// Compatibility response shape for older execution endpoints.
export interface RemediationExecutionResult {
execution_id: string;

View file

@ -16,29 +16,6 @@ import {
parseOptionalAPIResponseOrNull,
} from './responseUtils';
export interface RemovedDockerHost {
id: string;
hostname?: string;
displayName?: string;
removedAt: number;
}
export interface RemovedHostAgent {
id: string;
hostname?: string;
displayName?: string;
linkedVmId?: string;
linkedContainerId?: string;
removedAt: number;
}
export interface RemovedKubernetesCluster {
id: string;
name?: string;
displayName?: string;
removedAt: number;
}
async function deleteResource<T extends object>(
url: string,
parseErrorMessage: string,

View file

@ -201,14 +201,6 @@ export function apiErrorCode(error: unknown): string | null {
return trimmedOptionalString((error as APIErrorLike).code);
}
export function apiErrorDetail(error: unknown): string | null {
if (!error || typeof error !== 'object') {
return null;
}
return trimmedOptionalString((error as APIErrorLike).detail);
}
export function apiErrorDetails(error: unknown): Record<string, string> | null {
if (!error || typeof error !== 'object') {
return null;

View file

@ -359,5 +359,3 @@ export const formatInteger = (value?: number): string => {
if (value === undefined || value === null || Number.isNaN(value)) return '—';
return new Intl.NumberFormat().format(Math.round(value));
};
export const ALIAS_COLLAPSE_THRESHOLD = 4;

View file

@ -490,7 +490,3 @@ export const useResourceDetailDrawerDerivedState = (
tabs,
};
};
export type ResourceDetailDrawerDerivedState = ReturnType<
typeof useResourceDetailDrawerDerivedState
>;

View file

@ -95,7 +95,3 @@ export const useResourceDetailDrawerDockerActionsState = (
queueDockerUpdateAll,
};
};
export type UseResourceDetailDrawerDockerActionsStateResult = ReturnType<
typeof useResourceDetailDrawerDockerActionsState
>;

View file

@ -234,7 +234,3 @@ export const useResourceDetailDrawerHistoryState = (
refetchHistoryFacets,
};
};
export type ResourceDetailDrawerHistoryState = ReturnType<
typeof useResourceDetailDrawerHistoryState
>;

View file

@ -45,7 +45,3 @@ export function useUnifiedResourceTableViewportSync(
setHostBodyRef,
};
}
export type UnifiedResourceTableViewportSync = ReturnType<
typeof useUnifiedResourceTableViewportSync
>;

View file

@ -216,16 +216,3 @@ export function isModelProviderConfigured(
const provider = getProviderFromModelId(modelId);
return isAIProviderConfigured(provider, settings);
}
export function groupModelsByProvider(models: AIAvailableModel[]): Map<string, AIAvailableModel[]> {
const grouped = new Map<string, AIAvailableModel[]>();
for (const model of models) {
const provider = getProviderFromModelId(model.id);
const existing = grouped.get(provider) || [];
existing.push(model);
grouped.set(provider, existing);
}
return grouped;
}

View file

@ -48,34 +48,6 @@ export const matchConfiguredNodeToResource = (
});
};
export const collectConfiguredInfrastructureHosts = (nodes: NodeConfigWithStatus[]) => {
const configuredHosts = new Set<string>();
const clusterMemberIPs = new Set<string>();
nodes.forEach((node) => {
const cleanedHost = node.host.replace(/^https?:\/\//, '').replace(/:\d+$/, '');
configuredHosts.add(cleanedHost.toLowerCase());
if (!('isCluster' in node) || !node.isCluster || !('clusterEndpoints' in node)) {
return;
}
node.clusterEndpoints?.forEach((endpoint: ClusterEndpoint) => {
if (endpoint.ip) {
clusterMemberIPs.add(endpoint.ip.toLowerCase());
}
if (endpoint.host) {
clusterMemberIPs.add(endpoint.host.toLowerCase());
}
});
});
return {
clusterMemberIPs,
configuredHosts,
};
};
const createRepresentedDiscoveryHosts = (): RepresentedDiscoveryHosts => ({
pve: new Set<string>(),
pbs: new Set<string>(),

View file

@ -12,8 +12,6 @@ import type { DiscoverySettingsFormProps } from './discoverySettingsModel';
import type { TrueNASSettingsPanelState } from './useTrueNASSettingsPanelState';
import type { VMwareSettingsPanelState } from './useVMwareSettingsPanelState';
export type DiscoveryMode = 'auto' | 'custom';
export interface InfrastructurePlatformSettingsProps {
selectedAgent: Accessor<NodeType>;
onSelectAgent: (agent: NodeType) => void;

View file

@ -1,2 +1 @@
export type { ReportingResourceType } from '@/utils/reportingResourceTypes';
export { toReportingResourceType } from '@/utils/reportingResourceTypes';

View file

@ -1,16 +1,3 @@
export {
DEFAULT_SETTINGS_TAB,
agentKeyFromPlatformType,
deriveTabFromPath,
deriveTabFromQuery,
isRetiredSettingsCompatibilityPath,
isRouteableSettingsPath,
resolveCanonicalSettingsPath,
settingsAgentLabel,
settingsAgentNodeLabel,
settingsAgentPlatformType,
settingsTabPath,
type AgentKey,
type ProxmoxPlatformType,
type SettingsTab,
} from './settingsNavigationModel';

View file

@ -1,8 +1,3 @@
export type {
SettingsHeaderMeta,
SettingsHeaderMetaMap,
SettingsNavGroup,
SettingsNavGroupId,
SettingsNavItem,
SettingsTab,
} from './settingsNavigationModel';

View file

@ -559,5 +559,3 @@ Pulse prepares the first-host install token from setup so you can move straight
tokenName,
};
};
export type InfrastructureInstallState = ReturnType<typeof useInfrastructureInstallState>;

View file

@ -6,12 +6,6 @@ import { useInfrastructureDiscoveryRuntimeState } from './useInfrastructureDisco
import { useTrueNASSettingsPanelState } from './useTrueNASSettingsPanelState';
import { useVMwareSettingsPanelState } from './useVMwareSettingsPanelState';
export type {
DiscoveryScanStatus,
DiscoveredServer,
NodeType,
} from './infrastructureSettingsModel';
type InfrastructureEventBus = {
on<T extends EventType>(event: T, handler: (data?: EventDataMap[T]) => void): () => void;
};

View file

@ -1,3 +1,2 @@
export { SetupWizard } from './SetupWizard';
export { StepIndicator } from './StepIndicator';
export type { WizardState, WizardStep } from './SetupWizard';
export type { WizardState, } from './SetupWizard';

View file

@ -68,7 +68,6 @@ export const WORKLOAD_TABLE_HISTORY_RANGE_LABELS: Record<WorkloadTableMetricHist
'7d': '7d',
};
export const WORKLOAD_TABLE_HISTORY_DEFAULT_RANGE: WorkloadTableMetricHistoryRange = '1h';
export const WORKLOAD_TABLE_HISTORY_RANGE = WORKLOAD_TABLE_HISTORY_DEFAULT_RANGE;
export const WORKLOAD_TABLE_HISTORY_MAX_POINTS = 72;
export const WORKLOAD_TABLE_HISTORY_POLL_MS = 30_000;

View file

@ -88,7 +88,6 @@ export const DEFAULT_WORKLOADS_SORT_KEY: WorkloadsSortKey = 'type';
export const DEFAULT_WORKLOADS_SORT_DIRECTION = 'asc';
export const DEFAULT_WORKLOADS_VIEW_MODE: ViewMode = 'all';
export const DEFAULT_WORKLOADS_STATUS_MODE: WorkloadsStatusMode = 'all';
export const DEFAULT_WORKLOADS_GROUPING_MODE: WorkloadsGroupingMode = 'grouped';
export const DEFAULT_WORKLOADS_METRIC_DISPLAY_MODE: WorkloadsMetricDisplayMode = 'bars';
export const countActiveWorkloadsFilters = (

View file

@ -4,7 +4,6 @@ export { InvestigationSection } from './InvestigationSection';
export { InvestigationMessages } from './InvestigationMessages';
export { RemediationStatus } from './RemediationStatus';
export { RunToolCallTrace } from './RunToolCallTrace';
export { PatrolStatusBar } from './PatrolStatusBar';
export { RunHistoryEntry } from './RunHistoryEntry';
export { RunHistoryPanel } from './RunHistoryPanel';
export { CountdownTimer } from './CountdownTimer';

View file

@ -3,16 +3,13 @@ export { FilterChip } from './FilterChip';
export { AddFilterMenu } from './AddFilterMenu';
export { SavedViewsMenu } from './SavedViewsMenu';
export { useSavedViews } from './useSavedViews';
export type { SavedView, UseSavedViewsResult } from './useSavedViews';
export type { SavedView, } from './useSavedViews';
export {
clearFilter,
formatFilterChipValue,
isFilterSet,
} from './filterCatalog';
export type {
FilterBarProps,
FilterBarSearch,
FilterDef,
FilterGroupKey,
FilterSelectOption,
} from './filterCatalog';

View file

@ -10,7 +10,6 @@ import { useFilterButtonGroupState } from './useFilterButtonGroupState';
export type {
FilterButtonGroupProps,
FilterButtonGroupVariant,
FilterOption,
} from './filterButtonGroupModel';

View file

@ -16,7 +16,7 @@ import {
} from './pulseDataGridModel';
import { usePulseDataGridState } from './usePulseDataGridState';
export type { PulseDataGridProps, TableColumn } from './pulseDataGridModel';
export type { PulseDataGridProps, } from './pulseDataGridModel';
/**
* A standardized, responsive datagrid component for Pulse.

View file

@ -3,9 +3,6 @@ import { type SearchFieldProps } from './searchFieldModel';
import { useSearchFieldState } from './useSearchFieldState';
export type {
SearchFieldFocusEvent,
SearchFieldKeyboardEvent,
SearchFieldMouseEvent,
SearchFieldProps,
} from './searchFieldModel';

View file

@ -7,7 +7,7 @@ import {
import { type SearchInputProps } from './searchInputModel';
import { useSearchInputState } from './useSearchInputState';
export type { SearchInputKeyboardEvent, SearchInputProps } from './searchInputModel';
export type { SearchInputProps } from './searchInputModel';
export const SearchInput: Component<SearchInputProps> = (props) => {
const search = useSearchInputState(props);

View file

@ -11,7 +11,7 @@ import {
} from './searchTipsPopoverModel';
import { useSearchTipsPopoverState } from './useSearchTipsPopoverState';
export type { SearchTip, SearchTipsPopoverProps } from './searchTipsPopoverModel';
export type { SearchTipsPopoverProps } from './searchTipsPopoverModel';
export const SearchTipsPopover: Component<SearchTipsPopoverProps> = (props) => {
const triggerVariant = () => getSearchTipsPopoverTriggerVariant(props.triggerVariant);

View file

@ -11,9 +11,7 @@ import { useSelectionCardGroupState } from './useSelectionCardGroupState';
export type {
SelectionCardGroupProps,
SelectionCardGroupVariant,
SelectionCardOption,
SelectionCardTone,
} from './selectionCardGroupModel';
export function SelectionCardGroup<T extends string | number>(props: SelectionCardGroupProps<T>) {

View file

@ -153,85 +153,3 @@ export const ResponsiveMetricCell: Component<ResponsiveMetricCellProps> = (props
</Show>
);
};
/**
* Simpler metric text component for when you just want colored percentage
* without the MetricBar complexity
*/
export const MetricText: Component<{
value: number;
type: 'cpu' | 'memory' | 'disk';
label?: string;
class?: string;
thresholds?: MetricDisplayThresholds | null;
}> = (props) => {
const displayLabel = createMemo(() => props.label ?? formatPercent(props.value));
const colorClass = createMemo(() => metricTextClass(props.value, props.type, props.thresholds));
return (
<span class={`text-xs text-center ${colorClass()} ${props.class || ''}`}>
<Show when={!props.label} fallback={displayLabel()}>
<AnimatedNumber value={props.value} format={formatPercent} />
</Show>
</span>
);
};
/**
* Metric cell with explicit mobile/desktop rendering
* Use this when you need full control over what renders in each mode
*/
export const DualMetricCell: Component<{
value: number;
type: 'cpu' | 'memory' | 'disk';
label?: string;
sublabel?: string;
resourceId?: string;
isRunning?: boolean;
showMobile: boolean;
mobileContent?: JSX.Element;
desktopContent?: JSX.Element;
fallback?: JSX.Element;
class?: string;
thresholds?: MetricDisplayThresholds | null;
}> = (props) => {
const displayLabel = createMemo(() => props.label ?? formatPercent(props.value));
const colorClass = createMemo(() => metricTextClass(props.value, props.type, props.thresholds));
const isRunning = () => props.isRunning !== false;
const defaultFallback = (
<div class="h-4 flex items-center justify-center">
<span class="text-xs text-muted" aria-hidden="true"></span>
</div>
);
const defaultMobileContent = (
<div class={`text-xs text-center ${colorClass()}`}>
<Show when={!props.label} fallback={displayLabel()}>
<AnimatedNumber value={props.value} format={formatPercent} />
</Show>
</div>
);
const defaultDesktopContent = (
<MetricBar
value={props.value}
label={displayLabel()}
animatedLabelValue={props.label ? undefined : props.value}
sublabel={props.sublabel}
type={props.type}
resourceId={props.resourceId}
thresholds={props.thresholds}
/>
);
return (
<Show when={isRunning()} fallback={props.fallback ?? defaultFallback}>
<div class={props.class}>
<Show when={props.showMobile} fallback={props.desktopContent ?? defaultDesktopContent}>
{props.mobileContent ?? defaultMobileContent}
</Show>
</div>
</Show>
);
};

View file

@ -1,3 +1,3 @@
export const SUMMARY_CHART_SLOT_CLASS = 'h-[136px] sm:h-[150px]';
export const SUMMARY_CHART_SLOT_COMPACT_CLASS = 'h-[108px] sm:h-[120px]';
export const SUMMARY_CHART_PLOT_AREA_CLASS = 'h-[120px] sm:h-[134px]';

View file

@ -8,6 +8,3 @@ export const SUMMARY_TIME_RANGE_LABEL: Record<SummaryTimeRange, string> = {
'24h': '24h',
'7d': '7d',
};
export const isSummaryTimeRange = (value: string): value is SummaryTimeRange =>
(SUMMARY_TIME_RANGES as readonly string[]).includes(value);

View file

@ -73,5 +73,3 @@ export function useCommandPaletteState(props: CommandPaletteModalProps) {
setQuery,
};
}
export type CommandPaletteState = ReturnType<typeof useCommandPaletteState>;

View file

@ -126,5 +126,3 @@ export function useContainerUpdateButtonState(props: UpdateButtonProps) {
shouldHideButton,
};
}
export type ContainerUpdateButtonState = ReturnType<typeof useContainerUpdateButtonState>;

View file

@ -98,5 +98,3 @@ export function useHelpIconState(props: HelpIconProps) {
toggleOpen,
};
}
export type HelpIconState = ReturnType<typeof useHelpIconState>;

View file

@ -80,5 +80,3 @@ export function useMobileNavBarState(props: MobileNavBarProps) {
showLeftFade,
};
}
export type MobileNavBarState = ReturnType<typeof useMobileNavBarState>;

View file

@ -211,5 +211,3 @@ export function useWebInterfaceUrlFieldState(props: WebInterfaceUrlFieldProps) {
urlValue,
};
}
export type WebInterfaceUrlFieldState = ReturnType<typeof useWebInterfaceUrlFieldState>;

View file

@ -124,16 +124,6 @@ export const getGuestOverrideIdentity = (
};
};
export const canonicalGuestOverrideResourceId = (
resource: GuestOverrideResourceLike,
): string | undefined => {
const identity = getGuestOverrideIdentity(resource);
if (!identity) {
return undefined;
}
return `${identity.instance}:${identity.node}:${identity.vmid}`;
};
export const guestOverrideStorageId = (resource: GuestOverrideResourceLike): string => {
const identity = getGuestOverrideIdentity(resource);
if (!identity) {

View file

@ -40,17 +40,3 @@ export const stripStateKeys = (
delete (next as Record<string, unknown>).poweredOffSeverity;
return next;
};
export const removeOverrideState = (
overrides: Override[],
rawOverridesConfig: Record<string, RawOverrideConfig>,
resourceId: string,
) => {
const nextRawConfig = { ...rawOverridesConfig };
delete nextRawConfig[resourceId];
return {
nextOverrides: overrides.filter((override) => override.id !== resourceId),
nextRawConfig,
};
};

View file

@ -81,14 +81,6 @@ export const getStoragePoolTableColumns = (
colClassName: 'hidden xl:table-column xl:w-[11%]',
},
];
export const STORAGE_CONTROLS_NODE_SELECT_CLASS =
'px-2 py-1 text-xs border border-border rounded-md bg-surface text-base-content focus:ring-2 focus:ring-blue-500 focus:border-blue-500';
export const STORAGE_CONTROLS_NODE_DIVIDER_CLASS = 'h-5 w-px bg-surface-hover hidden sm:block';
export const STORAGE_CONTENT_CARD_HEADER_CLASS =
'border-b border-border bg-surface-hover px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-muted';
export const STORAGE_CONTENT_CARD_BODY_CLASS = 'p-2';
export const STORAGE_POOLS_EMPTY_STATE_CLASS = 'p-6 text-sm text-muted';

View file

@ -854,18 +854,6 @@ const matchesTrueNASStorageSearch = (resource: Resource, search: string): boolea
return haystack.includes(needle);
};
export function filterTrueNASStorageResources(
resources: Resource[],
search: string,
status: TrueNASStorageStatusFilter,
): Resource[] {
return resources.filter((resource) => {
if (!matchesTrueNASStorageSearch(resource, search)) return false;
if (status === 'all') return true;
return mapTrueNASStorageStatus(resource) === status;
});
}
const resourceIncidentLabel = (resource: Resource, incident: ResourceIncident): string => {
const label = asTrimmedString(resource.incidentLabel);
if (label) return label;

View file

@ -29,7 +29,6 @@ export const TRUENAS_DEFAULT_TAB = 'overview';
export const VMWARE_PATH = '/vmware';
export const VMWARE_DEFAULT_TAB = 'overview';
export const PMG_THRESHOLDS_PATH = '/alerts/thresholds/mail-gateway';
export const ALERTS_OVERVIEW_PATH = '/alerts/overview';
export const PATROL_PATH = '/patrol';
export const STORAGE_QUERY_PARAMS = {

View file

@ -191,18 +191,6 @@ export interface AIConversationMessage {
content: string;
}
// AI Execute request/response types
export interface AIExecuteRequest {
prompt: string;
target_type?: string; // "agent", "system-container", "vm", etc.
target_id?: string;
context?: Record<string, unknown>;
history?: AIConversationMessage[]; // Previous conversation messages
finding_id?: string; // If fixing a patrol finding, the ID to resolve on success
model?: string; // Override model for this request (user selection in chat)
use_case?: 'chat' | 'patrol'; // Optional server-side routing/model selection
}
// Tool execution info
export interface AIToolExecution {
name: string; // "run_command", "read_file"
@ -387,15 +375,6 @@ export interface AIChatMessage {
toolCalls?: AIChatToolCall[];
}
export interface AIChatSession {
id: string;
username: string;
title: string;
createdAt: Date;
updatedAt: Date;
messages: AIChatMessage[];
}
// Summary returned by list endpoint (no messages)
export interface AIChatSessionHandoffResource {
id?: string;

View file

@ -63,30 +63,6 @@ export interface ConnectedInfrastructureItem {
surfaces: ConnectedInfrastructureSurface[];
}
export interface KubernetesCluster {
id: string;
agentId: string;
name?: string;
displayName?: string;
customDisplayName?: string;
server?: string;
context?: string;
version?: string;
status: string;
lastSeen: number;
intervalSeconds: number;
agentVersion?: string;
tokenId?: string;
tokenName?: string;
tokenHint?: string;
tokenLastUsedAt?: number;
hidden?: boolean;
pendingUninstall?: boolean;
nodes?: KubernetesNode[];
pods?: KubernetesPod[];
deployments?: KubernetesDeployment[];
}
export interface KubernetesNode {
uid: string;
name: string;
@ -1068,11 +1044,6 @@ export interface PhysicalDisk {
smartAttributes?: SMARTAttributes;
}
/** Returns the best resource ID for disk metrics queries (serial preferred, WWN fallback). */
export function diskResourceId(disk: PhysicalDisk): string | null {
return disk.serial || disk.wwn || null;
}
export interface CPUInfo {
model: string;
cores: number;
@ -1259,7 +1230,3 @@ export type WSMessage =
scanning?: boolean;
};
};
// Utility types
export type Status = 'running' | 'stopped' | 'paused' | 'unknown';
export type GuestType = 'vm' | 'system-container';

View file

@ -87,15 +87,6 @@ export interface NodesConfig {
pbsInstances: PBSNodeConfig[];
}
/**
* Complete configuration structure
*/
export interface PulseConfig {
auth: Partial<AuthConfig>; // From .env
system: SystemConfig; // From system.json
nodes: NodesConfig; // From nodes.enc
}
/**
* API response for security status
*/
@ -180,47 +171,3 @@ export interface SSOProviderInfo {
iconUrl?: string;
loginUrl: string;
}
/**
* First-run setup request
*/
export interface SetupRequest {
username: string;
password: string;
apiToken?: string;
enableNotifications?: boolean;
darkMode?: boolean;
}
/**
* Type guards for configuration validation
*/
export const isValidUpdateChannel = (value: string): value is UpdateChannel => {
return value === 'stable' || value === 'rc';
};
export const isValidTimeFormat = (value: string): boolean => {
return /^([01]\d|2[0-3]):([0-5]\d)$/.test(value);
};
/**
* Default values for configuration
*/
export const DEFAULT_CONFIG: {
system: SystemConfig;
} = {
system: {
connectionTimeout: 60,
autoUpdateEnabled: false,
updateChannel: 'stable',
autoUpdateCheckInterval: 24,
autoUpdateTime: '03:00',
backupPollingEnabled: true,
backupPollingInterval: 0,
temperatureMonitoringEnabled: true,
telemetryEnabled: true,
sshPort: 22,
allowedOrigins: '',
frontendPort: 7655,
},
};

View file

@ -162,10 +162,6 @@ export interface UpdateNotesRequest {
user_secrets?: Record<string, string>;
}
export interface UpdateSettingsRequest {
max_discovery_age_days?: number; // Days before rediscovery (default 30)
}
// AI provider information for discovery transparency
export interface AIProviderInfo {
provider: string; // e.g., "anthropic", "openai", "ollama"

View file

@ -104,18 +104,3 @@ export type NodeConfigWithStatus = NodeConfig & {
hasToken?: boolean;
status: 'connected' | 'disconnected' | 'offline' | 'error' | 'pending';
};
export interface NodesResponse {
pve_instances: PVENodeConfig[];
pbs_instances: PBSNodeConfig[];
pmg_instances?: PMGNodeConfig[];
}
export interface NodeUpdateRequest {
node: NodeConfig;
}
export interface NodeDeleteResponse {
success: boolean;
message: string;
}

View file

@ -137,10 +137,6 @@ export interface RecoveryPointsSeriesBucket {
remote: number;
}
export interface RecoveryPointsSeriesResponse {
data: RecoveryPointsSeriesBucket[];
}
export interface RecoveryPointsFacets {
clusters?: string[];
nodesAgents?: string[];
@ -150,7 +146,3 @@ export interface RecoveryPointsFacets {
hasVerification?: boolean;
hasEntityId?: boolean;
}
export interface RecoveryPointsFacetsResponse {
data: RecoveryPointsFacets;
}

View file

@ -196,8 +196,6 @@ export const requiresGovernedResourceDisplay = (policy?: ResourcePolicy | null):
if (!policy) return false;
return policy.routing.scope === 'local-only' || (policy.routing.redact?.length ?? 0) > 0;
};
export type ResourceApprovalLevel = 'none' | 'dry_run_only' | 'admin' | 'mfa';
export type ResourceChangeConfidence = 'high' | 'medium' | 'low';
export type ResourceChangeKind =
| 'state_transition'

View file

@ -342,23 +342,6 @@ export const getFindingSeverityCompactLabel = (
severity: UnifiedFinding['severity'] | string,
): string => FINDING_SEVERITY_COMPACT_LABELS[severity] || String(severity).toUpperCase();
export const getFindingCompactBadgePresentation = (
finding: Pick<UnifiedFinding, 'severity' | 'resourceId' | 'resourceName' | 'title'>,
): FindingCompactBadgePresentation => {
if (isPatrolRuntimeFinding(finding)) {
const severityPresentation = getFindingSeverityPresentation(finding);
return {
label: severityPresentation.label,
badgeClasses: severityPresentation.badgeClasses,
};
}
return {
label: getFindingSeverityCompactLabel(finding.severity),
badgeClasses: getFindingSeverityBadgeClasses(finding.severity),
};
};
export const isPatrolRuntimeFinding = (
finding: Pick<UnifiedFinding, 'resourceId' | 'resourceName' | 'title'>,
): boolean => {
@ -617,25 +600,6 @@ export const doesFindingNeedAttention = (
);
};
// True when the finding has an investigation outcome indicating that some
// remediation step has run against it — anything past "fix queued." For these
// states, Verify fix is a meaningful action; for fix_queued (still awaiting
// approval) and earlier states there is nothing applied yet to verify, and
// for fix_failed the fix didn't complete so verification doesn't apply.
export const findingHasAppliedFix = (
finding: Pick<UnifiedFinding, 'investigationOutcome'>,
): boolean => {
switch (finding.investigationOutcome) {
case 'fix_executed':
case 'fix_verified':
case 'fix_verification_failed':
case 'fix_verification_unknown':
return true;
default:
return false;
}
};
export const getFindingLoopStateBadgeClasses = (loopState: string): string =>
FINDING_LOOP_STATE_CLASSES[loopState] || DEFAULT_LOOP_STATE_CLASSES;

View file

@ -190,10 +190,6 @@ export function getAlertConfigDiscardLabel(isReloading: boolean) {
return isReloading ? ALERT_CONFIG_DISCARDING_LABEL : ALERT_CONFIG_DISCARD_LABEL;
}
export function getAlertConfigSwarmGapValidationError() {
return ALERT_CONFIG_SWARM_GAP_VALIDATION;
}
export function getAlertConfigQuietHourSuppressOptions() {
return ALERT_CONFIG_QUIET_HOUR_SUPPRESS_OPTIONS;
}

View file

@ -275,17 +275,6 @@ export function getAlertWebhookUrlPlaceholder(urlPattern?: string) {
return urlPattern || ALERT_WEBHOOK_URL_PLACEHOLDER;
}
export function getAlertWebhookMentionPlaceholder(service: string) {
return (
ALERT_WEBHOOK_SERVICE_PRESENTATION[service as AlertWebhookService]?.mentionPlaceholder ||
ALERT_WEBHOOK_MENTION_FALLBACK_PLACEHOLDER
);
}
export function getAlertWebhookMentionHelp(service: string) {
return ALERT_WEBHOOK_SERVICE_PRESENTATION[service as AlertWebhookService]?.mentionHelp || '';
}
export function getAlertWebhookSummaryLabel(enabledCount: number, totalCount: number) {
return `${enabledCount} of ${totalCount} webhooks enabled`;
}

View file

@ -146,10 +146,6 @@ export function parseCloudTier(value?: string | null): CloudTierKey {
}
}
export function getCloudPlanForTier(value?: string | null): CloudPlanDefinition {
return CLOUD_PLAN_BY_TIER[parseCloudTier(value)];
}
export function getCloudPlanPricePresentation(
plan: CloudPlanDefinition,
): CloudPlanPricePresentation {

View file

@ -48,8 +48,6 @@ export interface HostedCommercialModelInput {
guestUsage: number;
renewsOrExpires: string;
}
export const SELF_HOSTED_NOT_METERED_LABEL = 'Not metered';
export const LIFETIME_DAYS_REMAINING_LABEL = 'Permanent';
const asUnlimitedLimit = (value?: number) =>

View file

@ -307,14 +307,6 @@ export function readInfrastructureSummaryCache(
}
}
export function hasFreshInfrastructureSummaryCache(
range: TimeRange,
maxAgeMs: number = INFRA_SUMMARY_CACHE_MAX_AGE_MS,
metrics?: readonly InfrastructureSummaryMetric[] | null,
): boolean {
return readInfrastructureSummaryCache(range, maxAgeMs, undefined, metrics) !== null;
}
const inFlightFetches = new Map<string, Promise<InfrastructureSummaryFetchResult>>();
let infraSummaryFetchSeq = 0;

View file

@ -60,10 +60,6 @@ export interface LicenseInlineNotice {
body: string;
}
export interface LicenseActionNotice extends LicenseInlineNotice {
actionLabel: string;
}
export interface BillingAdminOrganizationBadge {
label: string;
badgeClass: string;

View file

@ -758,13 +758,3 @@ export function getContainerRuntimeBadgeForRuntime(runtime?: string | null): Res
title: `Runtime: ${label}`,
};
}
export function getContainerRuntimeBadge(
platformType?: PlatformType,
platformData?: Record<string, unknown> | null,
): ResourceBadge | null {
if (platformType !== 'docker' || !platformData) return null;
const docker = (platformData as { docker?: { runtime?: string } } | undefined)?.docker;
return getContainerRuntimeBadgeForRuntime(docker?.runtime);
}

View file

@ -163,9 +163,3 @@ export const buildStorageSourceOptionsFromKeys = (
const orderedKeys = orderStorageSourceKeys(keys).filter((key) => key !== 'all');
return [ALL_STORAGE_SOURCE_OPTION, ...orderedKeys.map((key) => getStorageSourceOption(key))];
};
export const DEFAULT_STORAGE_SOURCE_OPTIONS: StorageSourceOption[] =
buildStorageSourceOptionsFromKeys(['proxmox-pve', 'proxmox-pbs', 'ceph', 'truenas']);
export const buildStorageSourceOptions = (storageList: Storage[]): StorageSourceOption[] =>
buildStorageSourceOptionsFromKeys(storageList.map((storage) => resolveStorageSourceKey(storage)));

View file

@ -48,11 +48,6 @@ export function fetchStorageSummaryAndCache(
return request;
}
export function __resetStorageSummaryCacheForTests(): void {
inMemoryCache.clear();
inFlightFetches.clear();
}
const unsubscribeStorageOrgSwitch = eventBus.on('org_switched', () => {
inMemoryCache.clear();
inFlightFetches.clear();

View file

@ -39,12 +39,6 @@ export function getUnifiedAgentLastSeenLabel(
return row.lastSeen ? formatRelativeTime(row.lastSeen) : '—';
}
export function getMonitoringStoppedEmptyState(hasFilters: boolean): string {
return hasFilters
? 'No monitoring-stopped items match the current filters.'
: 'No infrastructure currently has monitoring stopped.';
}
export function getUnifiedAgentStopMonitoringUnavailableMessage(): string {
return 'No host identifiers are available to stop monitoring.';
}

View file

@ -13,7 +13,6 @@ export interface UnifiedAgentLookupStatusPresentation {
}
export const MONITORING_STOPPED_STATUS_LABEL = 'Monitoring stopped';
export const ALLOW_RECONNECT_LABEL = 'Allow reconnect';
export function getUnifiedAgentStatusPresentation(
state: UnifiedAgentMonitoringState,

View file

@ -9,7 +9,6 @@ import { normalizeOrgScope } from '@/utils/orgScope';
import { eventBus } from '@/stores/events';
export const WORKLOADS_SUMMARY_CACHE_VERSION = 6;
export const WORKLOAD_CHART_DEFAULT_POINT_LIMIT = 180;
const WORKLOADS_SUMMARY_CACHE_PREFIX = 'pulse.workloadsSummaryCharts.';
const WORKLOADS_SUMMARY_CACHE_MAX_AGE_MS = 5 * 60_000;