185 lines
5.3 KiB
TypeScript

// src/components/dashboard/RouterTableLogic.tsx
import { useState, useMemo, useEffect, useCallback } from 'react';
import { RouterData, FilterType } from '../../types';
interface TimeoutInfo {
timeoutId: NodeJS.Timeout;
startTime: number;
}
interface AutoHideTimeouts {
[key: string]: TimeoutInfo;
}
export const useRouterTableLogic = (initialRouters: RouterData[] = []) => {
const [searchTerm, setSearchTerm] = useState('');
const [expandedRows, setExpandedRows] = useState<Set<string>>(new Set());
const [sortConfig, setSortConfig] = useState<{ key: keyof RouterData; direction: 'asc' | 'desc' } | null>(null);
const [timeLeft, setTimeLeft] = useState<{ [key: string]: number }>({});
const [autoHideTimeouts, setAutoHideTimeouts] = useState<AutoHideTimeouts>({});
const AUTO_HIDE_DELAY = 10000;
// Update countdown timer
useEffect(() => {
const interval = setInterval(() => {
setTimeLeft(prev => {
const now = Date.now();
const updated = { ...prev };
Object.entries(autoHideTimeouts).forEach(([key, info]) => {
if (info) {
const remaining = Math.max(0, AUTO_HIDE_DELAY - (now - info.startTime));
updated[key] = (remaining / AUTO_HIDE_DELAY) * 100;
}
});
return updated;
});
}, 100);
// Cleanup on unmount
return () => {
clearInterval(interval);
Object.values(autoHideTimeouts).forEach(info => {
if (info?.timeoutId) {
clearTimeout(info.timeoutId);
}
});
};
}, [autoHideTimeouts]);
// Filter and sort data
const filteredRouters = useMemo(() => {
const routers = Array.isArray(initialRouters) ? initialRouters : [];
let processed = [...routers];
if (searchTerm.trim()) {
const lowerSearchTerm = searchTerm.toLowerCase().trim();
processed = processed.filter(router => {
const searchableFields = ['routerId', 'routerAlias', 'facility'];
return searchableFields.some(field =>
String(router[field as keyof RouterData] || '')
.toLowerCase()
.includes(lowerSearchTerm)
);
});
}
if (sortConfig) {
processed.sort((a, b) => {
const aValue = a[sortConfig.key];
const bValue = b[sortConfig.key];
if (aValue < bValue) return sortConfig.direction === 'asc' ? -1 : 1;
if (aValue > bValue) return sortConfig.direction === 'asc' ? 1 : -1;
return 0;
});
}
return processed;
}, [initialRouters, searchTerm, sortConfig]);
const handleSort = useCallback((key: keyof RouterData) => {
setSortConfig(current => ({
key,
direction: current?.key === key && current.direction === 'asc' ? 'desc' : 'asc'
}));
}, []);
const toggleRowExpansion = useCallback((rowId: number, section: 'activity' | 'status' | 'disk') => {
const key = `${rowId}-${section}`;
setExpandedRows(prev => {
const next = new Set(prev);
if (next.has(key)) {
next.delete(key);
const existingTimeout = autoHideTimeouts[key]?.timeoutId;
if (existingTimeout) {
clearTimeout(existingTimeout);
setAutoHideTimeouts(prev => {
const next = { ...prev };
delete next[key];
return next;
});
setTimeLeft(prev => {
const next = { ...prev };
delete next[key];
return next;
});
}
} else {
next.add(key);
const timeoutId = setTimeout(() => {
setExpandedRows(prev => {
const next = new Set(prev);
next.delete(key);
return next;
});
setAutoHideTimeouts(prev => {
const next = { ...prev };
delete next[key];
return next;
});
setTimeLeft(prev => {
const next = { ...prev };
delete next[key];
return next;
});
}, AUTO_HIDE_DELAY);
setAutoHideTimeouts(prev => ({
...prev,
[key]: { timeoutId, startTime: Date.now() }
}));
setTimeLeft(prev => ({ ...prev, [key]: 100 }));
}
return next;
});
}, [autoHideTimeouts]);
const handleExpandedContentHover = useCallback((rowId: number, section: 'activity' | 'status' | 'disk') => {
const key = `${rowId}-${section}`;
const existingTimeout = autoHideTimeouts[key]?.timeoutId;
if (existingTimeout) {
clearTimeout(existingTimeout);
const timeoutId = setTimeout(() => {
setExpandedRows(prev => {
const next = new Set(prev);
next.delete(key);
return next;
});
setAutoHideTimeouts(prev => {
const next = { ...prev };
delete next[key];
return next;
});
setTimeLeft(prev => {
const next = { ...prev };
delete next[key];
return next;
});
}, AUTO_HIDE_DELAY);
setAutoHideTimeouts(prev => ({
...prev,
[key]: { timeoutId, startTime: Date.now() }
}));
setTimeLeft(prev => ({ ...prev, [key]: 100 }));
}
}, [autoHideTimeouts]);
return {
routers: filteredRouters,
totalRouters: initialRouters.length,
searchTerm,
setSearchTerm,
expandedRows,
timeLeft,
handleSort,
toggleRowExpansion,
handleExpandedContentHover
};
};