mirror of
https://github.com/LittleQuartZ/addmon.git
synced 2026-02-07 02:45:28 +07:00
feat(monitor): add search, status filter, and bulk invalid toggle
- Add search input to filter alerts by alertName or label values - Add status filter dropdown (All/Resolved/Unresolved) - Add Select All checkbox with indeterminate state for bulk invalid toggle - Add indeterminate prop support to Checkbox component - Add Monitor link to header navigation - Fix KPI dashboard padding for empty state
This commit is contained in:
parent
22aee93fb3
commit
c145d3fb07
8 changed files with 155 additions and 21 deletions
|
|
@ -106,6 +106,31 @@ pub struct ProcessedAlert {
|
|||
pub is_invalid: bool,
|
||||
pub attached_incident_id: Option<String>,
|
||||
pub values: HashMap<String, f64>,
|
||||
pub labels: HashMap<String, String>,
|
||||
}
|
||||
|
||||
fn parse_labels_from_text(text: &str) -> HashMap<String, String> {
|
||||
let mut labels = HashMap::new();
|
||||
|
||||
if let Some(start) = text.find('{') {
|
||||
if let Some(end) = text.rfind('}') {
|
||||
if start < end {
|
||||
let content = &text[start + 1..end];
|
||||
for pair in content.split(',') {
|
||||
let pair = pair.trim();
|
||||
if let Some(eq_pos) = pair.find('=') {
|
||||
let key = pair[..eq_pos].trim().to_string();
|
||||
let value = pair[eq_pos + 1..].trim().to_string();
|
||||
if !key.is_empty() {
|
||||
labels.insert(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
labels
|
||||
}
|
||||
|
||||
pub fn pair_alerts(raw_alerts: Vec<GrafanaAlert>) -> Vec<ProcessedAlert> {
|
||||
|
|
@ -126,6 +151,8 @@ pub fn pair_alerts(raw_alerts: Vec<GrafanaAlert>) -> Vec<ProcessedAlert> {
|
|||
let current = &alerts[i];
|
||||
|
||||
if current.new_state == "Alerting" {
|
||||
let labels = parse_labels_from_text(¤t.text);
|
||||
|
||||
if i + 1 < alerts.len() && alerts[i + 1].new_state == "Normal" {
|
||||
let resolve = &alerts[i + 1];
|
||||
let duration_ms = resolve.time.saturating_sub(current.time);
|
||||
|
|
@ -142,6 +169,7 @@ pub fn pair_alerts(raw_alerts: Vec<GrafanaAlert>) -> Vec<ProcessedAlert> {
|
|||
is_invalid: false,
|
||||
attached_incident_id: None,
|
||||
values: current.data.clone().map(|d| d.values).unwrap_or_default(),
|
||||
labels,
|
||||
});
|
||||
i += 2;
|
||||
} else {
|
||||
|
|
@ -157,6 +185,7 @@ pub fn pair_alerts(raw_alerts: Vec<GrafanaAlert>) -> Vec<ProcessedAlert> {
|
|||
is_invalid: false,
|
||||
attached_incident_id: None,
|
||||
values: current.data.clone().map(|d| d.values).unwrap_or_default(),
|
||||
labels,
|
||||
});
|
||||
i += 1;
|
||||
}
|
||||
|
|
@ -208,7 +237,7 @@ pub fn calculate_kpis(alerts: &[ProcessedAlert], incidents: &[Incident]) -> KpiM
|
|||
|
||||
let overall_downtime_ms: u64 = alerts
|
||||
.iter()
|
||||
.filter(|a| !a.is_invalid)
|
||||
.filter(|a| !a.is_invalid && a.attached_incident_id.is_some())
|
||||
.map(|a| a.duration_ms)
|
||||
.sum();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue