fix: remove unused runbook UI code to fix TypeScript errors
- Remove unused correlations state and constants from AIOverviewTable - Remove unused runbook-related imports, state, and functions from Alerts - Add type annotation to Set() to fix type error - Removes dead code left over from runbook UI removal
This commit is contained in:
parent
3e3de5325b
commit
547fb65e39
2 changed files with 5 additions and 88 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
import { Component, createEffect, createSignal, For, Show } from 'solid-js';
|
import { Component, createEffect, createSignal, For, Show } from 'solid-js';
|
||||||
import { AIAPI } from '@/api/ai';
|
import { AIAPI } from '@/api/ai';
|
||||||
import type { FailurePrediction, InfrastructureChange, RemediationRecord, RemediationStats, ResourceCorrelation, AnomalyReport } from '@/types/aiIntelligence';
|
import type { FailurePrediction, InfrastructureChange, RemediationRecord, RemediationStats, AnomalyReport } from '@/types/aiIntelligence';
|
||||||
|
|
||||||
const DEFAULT_UPGRADE_URL = 'https://pulsemonitor.app/pro';
|
const DEFAULT_UPGRADE_URL = 'https://pulsemonitor.app/pro';
|
||||||
|
|
||||||
|
|
@ -23,7 +23,6 @@ interface InsightRow {
|
||||||
*/
|
*/
|
||||||
export const AIOverviewTable: Component<{ showWhenEmpty?: boolean }> = (props) => {
|
export const AIOverviewTable: Component<{ showWhenEmpty?: boolean }> = (props) => {
|
||||||
const [predictions, setPredictions] = createSignal<FailurePrediction[]>([]);
|
const [predictions, setPredictions] = createSignal<FailurePrediction[]>([]);
|
||||||
const [correlations, setCorrelations] = createSignal<ResourceCorrelation[]>([]);
|
|
||||||
const [remediations, setRemediations] = createSignal<RemediationRecord[]>([]);
|
const [remediations, setRemediations] = createSignal<RemediationRecord[]>([]);
|
||||||
const [remediationStats, setRemediationStats] = createSignal<RemediationStats | null>(null);
|
const [remediationStats, setRemediationStats] = createSignal<RemediationStats | null>(null);
|
||||||
const [changes, setChanges] = createSignal<InfrastructureChange[]>([]);
|
const [changes, setChanges] = createSignal<InfrastructureChange[]>([]);
|
||||||
|
|
@ -42,12 +41,10 @@ export const AIOverviewTable: Component<{ showWhenEmpty?: boolean }> = (props) =
|
||||||
const [memoryLockedCount, setMemoryLockedCount] = createSignal(0);
|
const [memoryLockedCount, setMemoryLockedCount] = createSignal(0);
|
||||||
|
|
||||||
// Section expand/collapse state - default limits prevent overwhelming list
|
// Section expand/collapse state - default limits prevent overwhelming list
|
||||||
const [showAllDependencies, setShowAllDependencies] = createSignal(false);
|
|
||||||
const [showAllActions, setShowAllActions] = createSignal(false);
|
const [showAllActions, setShowAllActions] = createSignal(false);
|
||||||
const [showAllChanges, setShowAllChanges] = createSignal(false);
|
const [showAllChanges, setShowAllChanges] = createSignal(false);
|
||||||
|
|
||||||
// Limits for each section (when not expanded)
|
// Limits for each section (when not expanded)
|
||||||
const DEPENDENCY_LIMIT = 5;
|
|
||||||
const ACTION_LIMIT = 5;
|
const ACTION_LIMIT = 5;
|
||||||
const CHANGE_LIMIT = 5;
|
const CHANGE_LIMIT = 5;
|
||||||
|
|
||||||
|
|
@ -87,11 +84,9 @@ export const AIOverviewTable: Component<{ showWhenEmpty?: boolean }> = (props) =
|
||||||
const corrCount = corrResp.count || 0;
|
const corrCount = corrResp.count || 0;
|
||||||
setInsightsLockedCount(predCount + corrCount);
|
setInsightsLockedCount(predCount + corrCount);
|
||||||
setPredictions([]);
|
setPredictions([]);
|
||||||
setCorrelations([]);
|
|
||||||
} else {
|
} else {
|
||||||
setInsightsLockedCount(0);
|
setInsightsLockedCount(0);
|
||||||
setPredictions(predResp.predictions || []);
|
setPredictions(predResp.predictions || []);
|
||||||
setCorrelations(corrResp.correlations || []);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle impact lock
|
// Handle impact lock
|
||||||
|
|
@ -752,14 +747,6 @@ export const AIOverviewTable: Component<{ showWhenEmpty?: boolean }> = (props) =
|
||||||
<Show when={!loading() && anyHidden()}>
|
<Show when={!loading() && anyHidden()}>
|
||||||
<div class="px-4 py-2 border-t border-gray-100 dark:border-gray-700/50 bg-gray-50/50 dark:bg-gray-800/30">
|
<div class="px-4 py-2 border-t border-gray-100 dark:border-gray-700/50 bg-gray-50/50 dark:bg-gray-800/30">
|
||||||
<div class="flex flex-wrap items-center gap-3 text-xs">
|
<div class="flex flex-wrap items-center gap-3 text-xs">
|
||||||
<Show when={hiddenDependencies() > 0}>
|
|
||||||
<button
|
|
||||||
class="text-indigo-600 dark:text-indigo-400 hover:underline"
|
|
||||||
onClick={() => setShowAllDependencies(true)}
|
|
||||||
>
|
|
||||||
+ {hiddenDependencies()} more dependencies
|
|
||||||
</button>
|
|
||||||
</Show>
|
|
||||||
<Show when={hiddenActions() > 0}>
|
<Show when={hiddenActions() > 0}>
|
||||||
<button
|
<button
|
||||||
class="text-emerald-600 dark:text-emerald-400 hover:underline"
|
class="text-emerald-600 dark:text-emerald-400 hover:underline"
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import History from 'lucide-solid/icons/history';
|
||||||
import Gauge from 'lucide-solid/icons/gauge';
|
import Gauge from 'lucide-solid/icons/gauge';
|
||||||
import Send from 'lucide-solid/icons/send';
|
import Send from 'lucide-solid/icons/send';
|
||||||
import Calendar from 'lucide-solid/icons/calendar';
|
import Calendar from 'lucide-solid/icons/calendar';
|
||||||
import { getPatrolStatus, getFindings, getFindingsHistory, getPatrolRunHistory, forcePatrol, subscribeToPatrolStream, dismissFinding, suppressFinding, getSuppressionRules, addSuppressionRule, deleteSuppressionRule, getRunbooksForFinding, executeRunbook, type Finding, type PatrolStatus, type PatrolRunRecord, type SuppressionRule, type RunbookInfo, type RunbookExecutionResult, severityColors, formatTimestamp, categoryLabels } from '@/api/patrol';
|
import { getPatrolStatus, getFindings, getFindingsHistory, getPatrolRunHistory, forcePatrol, subscribeToPatrolStream, dismissFinding, suppressFinding, getSuppressionRules, addSuppressionRule, deleteSuppressionRule, type Finding, type PatrolStatus, type PatrolRunRecord, type SuppressionRule, severityColors, formatTimestamp, categoryLabels } from '@/api/patrol';
|
||||||
import { aiChatStore } from '@/stores/aiChat';
|
import { aiChatStore } from '@/stores/aiChat';
|
||||||
|
|
||||||
type AlertTab = 'overview' | 'thresholds' | 'destinations' | 'schedule' | 'history';
|
type AlertTab = 'overview' | 'thresholds' | 'destinations' | 'schedule' | 'history';
|
||||||
|
|
@ -2178,34 +2178,19 @@ function OverviewTab(props: {
|
||||||
const [newRuleDescription, setNewRuleDescription] = createSignal('');
|
const [newRuleDescription, setNewRuleDescription] = createSignal('');
|
||||||
const [licenseFeatures, setLicenseFeatures] = createSignal<LicenseFeatureStatus | null>(null);
|
const [licenseFeatures, setLicenseFeatures] = createSignal<LicenseFeatureStatus | null>(null);
|
||||||
const [licenseLoading, setLicenseLoading] = createSignal(false);
|
const [licenseLoading, setLicenseLoading] = createSignal(false);
|
||||||
const [runbooksByFinding, setRunbooksByFinding] = createSignal<Record<string, RunbookInfo[]>>({});
|
|
||||||
const [runbookLoadingByFinding, setRunbookLoadingByFinding] = createSignal<Record<string, boolean>>({});
|
|
||||||
const [runbookSelection, setRunbookSelection] = createSignal<Record<string, string>>({});
|
|
||||||
const [runbookResults, setRunbookResults] = createSignal<Record<string, RunbookExecutionResult | null>>({});
|
|
||||||
const [runbookErrors, setRunbookErrors] = createSignal<Record<string, string>>({});
|
|
||||||
const [expandedRunbookFinding, setExpandedRunbookFinding] = createSignal<string | null>(null);
|
|
||||||
const [remediationsByFinding, setRemediationsByFinding] = createSignal<Record<string, RemediationRecord[]>>({});
|
const [remediationsByFinding, setRemediationsByFinding] = createSignal<Record<string, RemediationRecord[]>>({});
|
||||||
const [remediationLoadingByFinding, setRemediationLoadingByFinding] = createSignal<Record<string, boolean>>({});
|
const [remediationLoadingByFinding, setRemediationLoadingByFinding] = createSignal<Record<string, boolean>>({});
|
||||||
const [remediationErrorsByFinding, setRemediationErrorsByFinding] = createSignal<Record<string, string>>({});
|
|
||||||
const [remediationLockedByFinding, setRemediationLockedByFinding] = createSignal<Record<string, boolean>>({});
|
|
||||||
const [remediationUpgradeURLByFinding, setRemediationUpgradeURLByFinding] = createSignal<Record<string, string>>({});
|
|
||||||
const hasAIAlertsFeature = createMemo(() => {
|
const hasAIAlertsFeature = createMemo(() => {
|
||||||
const status = licenseFeatures();
|
const status = licenseFeatures();
|
||||||
if (!status) return true;
|
if (!status) return true;
|
||||||
return Boolean(status.features?.['ai_alerts']);
|
return Boolean(status.features?.['ai_alerts']);
|
||||||
});
|
});
|
||||||
const hasAutoFixFeature = createMemo(() => {
|
|
||||||
const status = licenseFeatures();
|
|
||||||
if (!status) return false;
|
|
||||||
return Boolean(status.features?.['ai_autofix']);
|
|
||||||
});
|
|
||||||
const showAIAlertsUpgrade = createMemo(() => {
|
const showAIAlertsUpgrade = createMemo(() => {
|
||||||
const status = licenseFeatures();
|
const status = licenseFeatures();
|
||||||
if (!status) return false;
|
if (!status) return false;
|
||||||
return !status.features?.['ai_alerts'];
|
return !status.features?.['ai_alerts'];
|
||||||
});
|
});
|
||||||
const aiAlertsUpgradeURL = createMemo(() => licenseFeatures()?.upgrade_url || 'https://pulsemonitor.app/pro');
|
const aiAlertsUpgradeURL = createMemo(() => licenseFeatures()?.upgrade_url || 'https://pulsemonitor.app/pro');
|
||||||
const autoFixUpgradeURL = createMemo(() => licenseFeatures()?.upgrade_url || 'https://pulsemonitor.app/pro');
|
|
||||||
// Live streaming state for running patrol
|
// Live streaming state for running patrol
|
||||||
const [expandedLiveStream, setExpandedLiveStream] = createSignal(false);
|
const [expandedLiveStream, setExpandedLiveStream] = createSignal(false);
|
||||||
// Track streaming blocks for sequential display (like AI chat)
|
// Track streaming blocks for sequential display (like AI chat)
|
||||||
|
|
@ -2421,73 +2406,18 @@ function OverviewTab(props: {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadRunbooks = async (findingId: string) => {
|
|
||||||
setRunbookLoadingByFinding((prev) => ({ ...prev, [findingId]: true }));
|
|
||||||
setRunbookErrors((prev) => ({ ...prev, [findingId]: '' }));
|
|
||||||
try {
|
|
||||||
const runbooks = await getRunbooksForFinding(findingId);
|
|
||||||
setRunbooksByFinding((prev) => ({ ...prev, [findingId]: runbooks }));
|
|
||||||
if (runbooks.length > 0 && !runbookSelection()[findingId]) {
|
|
||||||
setRunbookSelection((prev) => ({ ...prev, [findingId]: runbooks[0].id }));
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
const message = err instanceof Error ? err.message : 'Failed to load runbooks';
|
|
||||||
setRunbookErrors((prev) => ({ ...prev, [findingId]: message }));
|
|
||||||
} finally {
|
|
||||||
setRunbookLoadingByFinding((prev) => ({ ...prev, [findingId]: false }));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleRunbookPanel = (findingId: string) => {
|
|
||||||
setExpandedRunbookFinding((prev) => (prev === findingId ? null : findingId));
|
|
||||||
if (!runbooksByFinding()[findingId] && !runbookLoadingByFinding()[findingId]) {
|
|
||||||
void loadRunbooks(findingId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadRemediationsForFinding = async (findingId: string) => {
|
const loadRemediationsForFinding = async (findingId: string) => {
|
||||||
setRemediationLoadingByFinding((prev) => ({ ...prev, [findingId]: true }));
|
setRemediationLoadingByFinding((prev) => ({ ...prev, [findingId]: true }));
|
||||||
setRemediationErrorsByFinding((prev) => ({ ...prev, [findingId]: '' }));
|
|
||||||
try {
|
try {
|
||||||
const response = await AIAPI.getRemediations({ findingId, limit: 3 });
|
const response = await AIAPI.getRemediations({ findingId, limit: 3 });
|
||||||
const locked = Boolean(response.license_required);
|
setRemediationsByFinding((prev) => ({ ...prev, [findingId]: response.remediations || [] }));
|
||||||
setRemediationLockedByFinding((prev) => ({ ...prev, [findingId]: locked }));
|
|
||||||
if (response.upgrade_url) {
|
|
||||||
setRemediationUpgradeURLByFinding((prev) => ({ ...prev, [findingId]: response.upgrade_url || '' }));
|
|
||||||
}
|
|
||||||
setRemediationsByFinding((prev) => ({ ...prev, [findingId]: locked ? [] : (response.remediations || []) }));
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const message = err instanceof Error ? err.message : 'Failed to load remediation history';
|
console.error('Failed to load remediation history', err);
|
||||||
setRemediationErrorsByFinding((prev) => ({ ...prev, [findingId]: message }));
|
|
||||||
} finally {
|
} finally {
|
||||||
setRemediationLoadingByFinding((prev) => ({ ...prev, [findingId]: false }));
|
setRemediationLoadingByFinding((prev) => ({ ...prev, [findingId]: false }));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const runSelectedRunbook = async (findingId: string) => {
|
|
||||||
const runbookId = runbookSelection()[findingId];
|
|
||||||
if (!runbookId) {
|
|
||||||
setRunbookErrors((prev) => ({ ...prev, [findingId]: 'Select a runbook to execute.' }));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setRunbookErrors((prev) => ({ ...prev, [findingId]: '' }));
|
|
||||||
setRunbookResults((prev) => ({ ...prev, [findingId]: null }));
|
|
||||||
setRunbookLoadingByFinding((prev) => ({ ...prev, [findingId]: true }));
|
|
||||||
try {
|
|
||||||
const result = await executeRunbook(findingId, runbookId);
|
|
||||||
setRunbookResults((prev) => ({ ...prev, [findingId]: result }));
|
|
||||||
if (result.resolved) {
|
|
||||||
fetchAiData();
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
const message = err instanceof Error ? err.message : 'Runbook execution failed';
|
|
||||||
setRunbookErrors((prev) => ({ ...prev, [findingId]: message }));
|
|
||||||
} finally {
|
|
||||||
setRunbookLoadingByFinding((prev) => ({ ...prev, [findingId]: false }));
|
|
||||||
void loadRemediationsForFinding(findingId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle force patrol button click
|
// Handle force patrol button click
|
||||||
const handleForcePatrol = async (deep: boolean = false) => {
|
const handleForcePatrol = async (deep: boolean = false) => {
|
||||||
setForcePatrolLoading(true);
|
setForcePatrolLoading(true);
|
||||||
|
|
@ -5826,7 +5756,7 @@ function HistoryTab() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setResourceIncidentPanel({ resourceId, resourceName });
|
setResourceIncidentPanel({ resourceId, resourceName });
|
||||||
setExpandedResourceIncidentIds(new Set());
|
setExpandedResourceIncidentIds(new Set<string>());
|
||||||
if (!(resourceId in resourceIncidents())) {
|
if (!(resourceId in resourceIncidents())) {
|
||||||
await loadResourceIncidents(resourceId);
|
await loadResourceIncidents(resourceId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue