103 lines
2.6 KiB
TypeScript
103 lines
2.6 KiB
TypeScript
/**
|
|
* 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,
|
|
};
|
|
}
|