feat: Implement network metrics integration and UI updates for real-time data display

This commit is contained in:
Juergen Kunz
2025-06-20 10:56:53 +00:00
parent b81bda6ce8
commit 92fde9d0d7
5 changed files with 377 additions and 48 deletions

View File

@ -43,6 +43,16 @@ export interface ILogState {
};
}
export interface INetworkState {
connections: interfaces.data.IConnectionInfo[];
connectionsByIP: { [ip: string]: number };
throughputRate: { bytesInPerSecond: number; bytesOutPerSecond: number };
topIPs: Array<{ ip: string; count: number }>;
lastUpdated: number;
isLoading: boolean;
error: string | null;
}
// Create state parts with appropriate persistence
export const loginStatePart = await appState.getStatePart<ILoginState>(
'login',
@ -97,6 +107,20 @@ export const logStatePart = await appState.getStatePart<ILogState>(
'soft'
);
export const networkStatePart = await appState.getStatePart<INetworkState>(
'network',
{
connections: [],
connectionsByIP: {},
throughputRate: { bytesInPerSecond: 0, bytesOutPerSecond: 0 },
topIPs: [],
lastUpdated: 0,
isLoading: false,
error: null,
},
'soft'
);
// Actions for state management
interface IActionContext {
identity: interfaces.data.IIdentity | null;
@ -324,6 +348,68 @@ export const setActiveViewAction = uiStatePart.createAction<string>(async (state
};
});
// Fetch Network Stats Action
export const fetchNetworkStatsAction = networkStatePart.createAction(async (statePartArg) => {
const context = getActionContext();
const currentState = statePartArg.getState();
try {
// Fetch active connections using the existing endpoint
const connectionsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
interfaces.requests.IReq_GetActiveConnections
>('/typedrequest', 'getActiveConnections');
const connectionsResponse = await connectionsRequest.fire({
identity: context.identity,
});
// Get network stats for throughput and IP data
const networkStatsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest(
'/typedrequest',
'getNetworkStats'
);
const networkStatsResponse = await networkStatsRequest.fire({
identity: context.identity,
}) as any;
// Use the connections data for the connection list
// and network stats for throughput and IP analytics
const connectionsByIP: { [ip: string]: number } = {};
// Build connectionsByIP from network stats if available
if (networkStatsResponse.connectionsByIP && Array.isArray(networkStatsResponse.connectionsByIP)) {
networkStatsResponse.connectionsByIP.forEach((item: { ip: string; count: number }) => {
connectionsByIP[item.ip] = item.count;
});
} else {
// Fallback: calculate from connections
connectionsResponse.connections.forEach(conn => {
const ip = conn.remoteAddress;
connectionsByIP[ip] = (connectionsByIP[ip] || 0) + 1;
});
}
return {
connections: connectionsResponse.connections,
connectionsByIP,
throughputRate: networkStatsResponse.throughputRate || { bytesInPerSecond: 0, bytesOutPerSecond: 0 },
topIPs: networkStatsResponse.topIPs || [],
lastUpdated: Date.now(),
isLoading: false,
error: null,
};
} catch (error) {
console.error('Failed to fetch network stats:', error);
return {
...currentState,
isLoading: false,
error: error instanceof Error ? error.message : 'Failed to fetch network stats',
};
}
});
// Initialize auto-refresh
let refreshInterval: NodeJS.Timeout | null = null;
@ -334,6 +420,7 @@ let refreshInterval: NodeJS.Timeout | null = null;
if (uiState.autoRefresh && loginStatePart.getState().isLoggedIn) {
refreshInterval = setInterval(() => {
statsStatePart.dispatchAction(fetchAllStatsAction, null);
networkStatePart.dispatchAction(fetchNetworkStatsAction, null);
}, uiState.refreshInterval);
}
};