Improve the frontend
This commit is contained in:
102
frontend/src/hooks/useAlertGrouping.ts
Normal file
102
frontend/src/hooks/useAlertGrouping.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* useAlertGrouping Hook
|
||||
* Manages alert grouping logic and state
|
||||
*/
|
||||
|
||||
import { useMemo, useState, useCallback } from 'react';
|
||||
import { NotificationData } from './useNotifications';
|
||||
import {
|
||||
groupAlertsByTime,
|
||||
groupAlertsByCategory,
|
||||
groupSimilarAlerts,
|
||||
sortAlerts,
|
||||
type AlertGroup,
|
||||
} from '../utils/alertHelpers';
|
||||
|
||||
export type GroupingMode = 'none' | 'time' | 'category' | 'similarity';
|
||||
|
||||
export interface UseAlertGroupingReturn {
|
||||
groupedAlerts: AlertGroup[];
|
||||
groupingMode: GroupingMode;
|
||||
setGroupingMode: (mode: GroupingMode) => void;
|
||||
collapsedGroups: Set<string>;
|
||||
toggleGroupCollapse: (groupId: string) => void;
|
||||
collapseAll: () => void;
|
||||
expandAll: () => void;
|
||||
isGroupCollapsed: (groupId: string) => boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to manage alert grouping
|
||||
*/
|
||||
export function useAlertGrouping(
|
||||
alerts: NotificationData[],
|
||||
initialMode: GroupingMode = 'time'
|
||||
): UseAlertGroupingReturn {
|
||||
const [groupingMode, setGroupingMode] = useState<GroupingMode>(initialMode);
|
||||
const [collapsedGroups, setCollapsedGroups] = useState<Set<string>>(new Set());
|
||||
|
||||
const groupedAlerts = useMemo(() => {
|
||||
// Sort alerts first
|
||||
const sortedAlerts = sortAlerts(alerts);
|
||||
|
||||
switch (groupingMode) {
|
||||
case 'time':
|
||||
return groupAlertsByTime(sortedAlerts);
|
||||
|
||||
case 'category':
|
||||
return groupAlertsByCategory(sortedAlerts);
|
||||
|
||||
case 'similarity':
|
||||
return groupSimilarAlerts(sortedAlerts);
|
||||
|
||||
case 'none':
|
||||
default:
|
||||
// Return each alert as its own group
|
||||
return sortedAlerts.map((alert, index) => ({
|
||||
id: `single-${alert.id}`,
|
||||
type: 'time' as const,
|
||||
key: alert.id,
|
||||
title: alert.title,
|
||||
count: 1,
|
||||
severity: alert.severity as any,
|
||||
alerts: [alert],
|
||||
}));
|
||||
}
|
||||
}, [alerts, groupingMode]);
|
||||
|
||||
const toggleGroupCollapse = useCallback((groupId: string) => {
|
||||
setCollapsedGroups(prev => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(groupId)) {
|
||||
next.delete(groupId);
|
||||
} else {
|
||||
next.add(groupId);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const collapseAll = useCallback(() => {
|
||||
setCollapsedGroups(new Set(groupedAlerts.map(g => g.id)));
|
||||
}, [groupedAlerts]);
|
||||
|
||||
const expandAll = useCallback(() => {
|
||||
setCollapsedGroups(new Set());
|
||||
}, []);
|
||||
|
||||
const isGroupCollapsed = useCallback((groupId: string) => {
|
||||
return collapsedGroups.has(groupId);
|
||||
}, [collapsedGroups]);
|
||||
|
||||
return {
|
||||
groupedAlerts,
|
||||
groupingMode,
|
||||
setGroupingMode,
|
||||
collapsedGroups,
|
||||
toggleGroupCollapse,
|
||||
collapseAll,
|
||||
expandAll,
|
||||
isGroupCollapsed,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user