feat(monitor): add alert pairing logic and display incident names

- Add pair_alerts() to pair consecutive Alerting→Normal state transitions
- Add parse_labels_from_text() to extract labels from alert text field
- Update ProcessedAlert struct with alertTime, resolveTime, isResolved, labels
- Display incident name in alert list items instead of incident ID
- Show parsed labels in alert row (excluding alertname)
This commit is contained in:
Syahdan 2025-12-29 06:07:13 +07:00
parent ea1c9105a7
commit 22aee93fb3
6 changed files with 165 additions and 129 deletions

View file

@ -72,25 +72,17 @@ function MonitorPage() {
}
};
const handleToggleInvalid = async (alertId: number, isInvalid: boolean) => {
try {
const updatedAlerts = await invoke<ProcessedAlert[]>(
"set_alert_invalid",
{
alerts,
alertId,
isInvalid,
},
const handleToggleInvalid = (alertId: number, isInvalid: boolean) => {
setAlerts((prev) => {
const updated = prev.map((a) =>
a.id === alertId ? { ...a, isInvalid } : a,
);
setAlerts(updatedAlerts);
await recalculateKpis(updatedAlerts, incidents);
recalculateKpis(updated, incidents);
return updated;
});
if (selectedAlert?.id === alertId) {
const updated = updatedAlerts.find((a) => a.id === alertId);
if (updated) setSelectedAlert(updated);
}
} catch (err) {
setError(err instanceof Error ? err.message : String(err));
if (selectedAlert?.id === alertId) {
setSelectedAlert((prev) => (prev ? { ...prev, isInvalid } : null));
}
};
@ -108,50 +100,55 @@ function MonitorPage() {
recalculateKpis(alerts, newIncidents);
};
const handleAttachAlert = async (alertId: number, incidentId: string) => {
try {
const [updatedAlerts, updatedIncidents] = await invoke<
[ProcessedAlert[], Incident[]]
>("attach_alert_to_incident", {
alerts,
incidents,
alertId,
incidentId,
});
const handleAttachAlert = (alertId: number, incidentId: string) => {
const updatedAlerts = alerts.map((a) =>
a.id === alertId ? { ...a, attachedIncidentId: incidentId } : a,
);
const updatedIncidents = incidents.map((i) =>
i.id === incidentId && !i.attachedAlertIds.includes(alertId)
? { ...i, attachedAlertIds: [...i.attachedAlertIds, alertId] }
: i,
);
setAlerts(updatedAlerts);
setIncidents(updatedIncidents);
await recalculateKpis(updatedAlerts, updatedIncidents);
setAlerts(updatedAlerts);
setIncidents(updatedIncidents);
recalculateKpis(updatedAlerts, updatedIncidents);
if (selectedAlert?.id === alertId) {
const updated = updatedAlerts.find((a) => a.id === alertId);
if (updated) setSelectedAlert(updated);
}
} catch (err) {
setError(err instanceof Error ? err.message : String(err));
if (selectedAlert?.id === alertId) {
setSelectedAlert((prev) =>
prev ? { ...prev, attachedIncidentId: incidentId } : null,
);
}
};
const handleDetachAlert = async (alertId: number) => {
try {
const [updatedAlerts, updatedIncidents] = await invoke<
[ProcessedAlert[], Incident[]]
>("detach_alert_from_incident", {
alerts,
incidents,
alertId,
});
const handleDetachAlert = (alertId: number) => {
const alert = alerts.find((a) => a.id === alertId);
const incidentId = alert?.attachedIncidentId;
setAlerts(updatedAlerts);
setIncidents(updatedIncidents);
await recalculateKpis(updatedAlerts, updatedIncidents);
const updatedAlerts = alerts.map((a) =>
a.id === alertId ? { ...a, attachedIncidentId: null } : a,
);
const updatedIncidents = incidentId
? incidents.map((i) =>
i.id === incidentId
? {
...i,
attachedAlertIds: i.attachedAlertIds.filter(
(aid) => aid !== alertId,
),
}
: i,
)
: incidents;
if (selectedAlert?.id === alertId) {
const updated = updatedAlerts.find((a) => a.id === alertId);
if (updated) setSelectedAlert(updated);
}
} catch (err) {
setError(err instanceof Error ? err.message : String(err));
setAlerts(updatedAlerts);
setIncidents(updatedIncidents);
recalculateKpis(updatedAlerts, updatedIncidents);
if (selectedAlert?.id === alertId) {
setSelectedAlert((prev) =>
prev ? { ...prev, attachedIncidentId: null } : null,
);
}
};
@ -197,6 +194,7 @@ function MonitorPage() {
) : (
<AlertList
alerts={alerts}
incidents={incidents}
onToggleInvalid={handleToggleInvalid}
onSelectAlert={handleSelectAlert}
selectedAlertId={selectedAlert?.id}