Improved the Server feature History Data

This commit is contained in:
Tola Leng
2025-07-21 22:18:27 +07:00
parent d17a70dfa8
commit 2d2122d2e5
12 changed files with 155 additions and 168 deletions
@@ -78,7 +78,7 @@ export const EditServerDialog: React.FC<EditServerDialogProps> = ({
// Initialize form data when server changes
useEffect(() => {
if (server) {
console.log("Setting form data for server:", server);
// console.log("Setting form data for server:", server);
// Parse comma-separated notification_id into array
const notificationChannels = server.notification_id
? server.notification_id.split(',').map(id => id.trim()).filter(id => id)
@@ -109,10 +109,10 @@ export const EditServerDialog: React.FC<EditServerDialogProps> = ({
// Load existing threshold data when thresholds are loaded and we have a server with threshold_id
useEffect(() => {
if (server && server.threshold_id && thresholds.length > 0) {
console.log("Loading existing threshold data for server:", server.threshold_id);
// console.log("Loading existing threshold data for server:", server.threshold_id);
const existingThreshold = thresholds.find(t => t.id === server.threshold_id);
if (existingThreshold) {
console.log("Found existing threshold:", existingThreshold);
// console.log("Found existing threshold:", existingThreshold);
setSelectedThreshold(existingThreshold);
// Handle the API response format with proper field names and type conversion
setThresholdFormData({
@@ -166,7 +166,7 @@ export const EditServerDialog: React.FC<EditServerDialogProps> = ({
const configs = await alertConfigService.getAlertConfigurations();
setAlertConfigs(configs);
} catch (error) {
console.error('Error loading alert configurations:', error);
// console.error('Error loading alert configurations:', error);
toast({
variant: "destructive",
title: "Error",
@@ -183,7 +183,7 @@ export const EditServerDialog: React.FC<EditServerDialogProps> = ({
const templateList = await templateService.getTemplates();
setTemplates(templateList);
} catch (error) {
console.error('Error loading templates:', error);
// console.error('Error loading templates:', error);
toast({
variant: "destructive",
title: "Error",
@@ -200,7 +200,7 @@ export const EditServerDialog: React.FC<EditServerDialogProps> = ({
const thresholdList = await serverThresholdService.getServerThresholds();
setThresholds(thresholdList);
} catch (error) {
console.error('Error loading server thresholds:', error);
// console.error('Error loading server thresholds:', error);
toast({
variant: "destructive",
title: "Error",
@@ -243,7 +243,7 @@ export const EditServerDialog: React.FC<EditServerDialogProps> = ({
description: "Server threshold values have been updated successfully.",
});
} catch (error) {
console.error('Error updating threshold:', error);
// console.error('Error updating threshold:', error);
toast({
variant: "destructive",
title: "Error",
@@ -301,7 +301,7 @@ export const EditServerDialog: React.FC<EditServerDialogProps> = ({
onOpenChange(false);
} catch (error) {
console.error('Error updating server:', error);
// console.error('Error updating server:', error);
toast({
variant: "destructive",
title: "Error",
@@ -24,7 +24,7 @@ export const ServerHistoryCharts = ({ serverId }: ServerHistoryChartsProps) => {
isFetching
} = useServerHistoryData(serverId);
console.log('ServerHistoryCharts: Rendering with serverId:', serverId, 'timeRange:', timeRange);
// console.log('ServerHistoryCharts: Rendering with serverId:', serverId, 'timeRange:', timeRange);
// Memoize latest data calculation to prevent unnecessary recalculations
const latestData = useMemo(() => {
@@ -71,7 +71,7 @@ export const ServerHistoryCharts = ({ serverId }: ServerHistoryChartsProps) => {
}
if (error) {
console.error('ServerHistoryCharts: Error loading data:', error);
// console.error('ServerHistoryCharts: Error loading data:', error);
return (
<div className="space-y-4">
<div className="flex items-center justify-between">
@@ -122,7 +122,7 @@ export const ServerHistoryCharts = ({ serverId }: ServerHistoryChartsProps) => {
);
}
console.log('ServerHistoryCharts: Rendering charts with', chartData.length, 'data points for time range:', timeRange);
// console.log('ServerHistoryCharts: Rendering charts with', chartData.length, 'data points for time range:', timeRange);
return (
<div className="space-y-6">
@@ -59,39 +59,26 @@ export const ServerTable = ({ servers, isLoading, onRefresh }: ServerTableProps)
try {
setPausingServers(prev => new Set(prev).add(serverId));
if (isPaused) {
// Resume monitoring
await pb.collection('servers').update(serverId, {
status: "up",
last_checked: new Date().toISOString()
});
toast({
title: "Server resumed",
description: `Monitoring resumed for ${server.name}`,
});
console.log(`Resume server monitoring: ${serverId}`);
} else {
// Pause monitoring
await pb.collection('servers').update(serverId, {
status: "paused",
last_checked: new Date().toISOString()
});
toast({
title: "Server paused",
description: `Monitoring paused for ${server.name}`,
});
console.log(`Pause server monitoring: ${serverId}`);
}
// Only update the status field, preserving all other server configuration
const updateData = {
status: isPaused ? "up" : "paused",
last_checked: new Date().toISOString()
};
await pb.collection('servers').update(serverId, updateData);
toast({
title: isPaused ? "Server resumed" : "Server paused",
description: `Monitoring ${isPaused ? 'resumed' : 'paused'} for ${server.name}`,
});
// console.log(`${isPaused ? 'Resume' : 'Pause'} server monitoring: ${serverId}`);
// Refresh the server list to show updated status
onRefresh();
} catch (error) {
console.error('Error updating server status:', error);
// console.error('Error updating server status:', error);
toast({
variant: "destructive",
title: "Error",
@@ -138,7 +125,7 @@ export const ServerTable = ({ servers, isLoading, onRefresh }: ServerTableProps)
setSelectedServer(null);
} catch (error) {
console.error('Error deleting server:', error);
// console.error('Error deleting server:', error);
toast({
variant: "destructive",
title: "Error",
@@ -50,21 +50,21 @@ export const timeRangeOptions = [
export const filterMetricsByTimeRange = (metrics: any[], timeRange: TimeRange): any[] => {
if (!metrics?.length) {
console.log('🔍 filterMetricsByTimeRange: No metrics provided');
// console.log('🔍 filterMetricsByTimeRange: No metrics provided');
return [];
}
console.log('🔍 filterMetricsByTimeRange: Starting with', metrics.length, 'metrics for', timeRange);
//console.log('🔍 filterMetricsByTimeRange: Starting with', metrics.length, 'metrics for', timeRange);
const now = new Date();
// For 60m, let's be very specific about what we're looking for
if (timeRange === '60m') {
console.log('⏰ 60m filter: Current time:', now.toISOString());
// console.log('⏰ 60m filter: Current time:', now.toISOString());
// Try exact 60 minutes first
const cutoffTime60m = new Date(now.getTime() - (60 * 60 * 1000));
console.log('⏰ 60m filter: Cutoff time:', cutoffTime60m.toISOString());
// console.log('⏰ 60m filter: Cutoff time:', cutoffTime60m.toISOString());
const filtered60m = metrics.filter(metric => {
const metricTime = new Date(metric.created || metric.timestamp);
@@ -72,17 +72,17 @@ export const filterMetricsByTimeRange = (metrics: any[], timeRange: TimeRange):
if (!isWithinRange) {
const ageMinutes = Math.round((now.getTime() - metricTime.getTime()) / (1000 * 60));
console.log('⏰ Excluding record:', {
created: metric.created || metric.timestamp,
ageMinutes: ageMinutes,
reason: ageMinutes > 60 ? 'too old' : 'future date'
});
// console.log('⏰ Excluding record:', {
// created: metric.created || metric.timestamp,
// ageMinutes: ageMinutes,
// reason: ageMinutes > 60 ? 'too old' : 'future date'
// });
}
return isWithinRange;
});
console.log('✅ 60m strict filter result:', filtered60m.length, 'records');
// console.log('✅ 60m strict filter result:', filtered60m.length, 'records');
if (filtered60m.length > 0) {
return filtered60m.sort((a, b) =>
@@ -91,18 +91,18 @@ export const filterMetricsByTimeRange = (metrics: any[], timeRange: TimeRange):
}
// If no data in exactly 60m, show what we have and return it anyway for debugging
console.log('⚠️ No data in 60m range, showing all available data ages:');
// console.log('⚠️ No data in 60m range, showing all available data ages:');
metrics.forEach((metric, index) => {
const metricTime = new Date(metric.created || metric.timestamp);
const ageMinutes = Math.round((now.getTime() - metricTime.getTime()) / (1000 * 60));
console.log(`Record ${index}: ${metric.created || metric.timestamp} (${ageMinutes} minutes ago)`);
// console.log(`Record ${index}: ${metric.created || metric.timestamp} (${ageMinutes} minutes ago)`);
});
// Return the most recent data regardless of age
const sorted = metrics.sort((a, b) =>
new Date(b.created || b.timestamp).getTime() - new Date(a.created || a.timestamp).getTime()
);
console.log('🔄 Returning most recent available data for 60m view');
// console.log('🔄 Returning most recent available data for 60m view');
return sorted.slice(0, 20); // Show last 20 records
}
@@ -117,7 +117,7 @@ export const filterMetricsByTimeRange = (metrics: any[], timeRange: TimeRange):
return metricTime >= cutoffTime && metricTime <= now;
});
console.log('✅ Filtered', metrics.length, 'to', filtered.length, 'metrics for', timeRange);
// console.log('✅ Filtered', metrics.length, 'to', filtered.length, 'metrics for', timeRange);
return filtered.sort((a, b) =>
new Date(a.created || a.timestamp).getTime() - new Date(b.created || b.timestamp).getTime()
@@ -174,27 +174,27 @@ const formatTimestamp = (timestamp: string, timeRange: TimeRange): string => {
};
export const formatChartData = (metrics: any[], timeRange: TimeRange) => {
console.log('📊 formatChartData: Processing', {
inputCount: metrics?.length || 0,
timeRange,
sampleMetric: metrics?.[0] ? {
id: metrics[0].id,
created: metrics[0].created,
timestamp: metrics[0].timestamp,
server_id: metrics[0].server_id
} : null
});
// console.log('📊 formatChartData: Processing', {
// inputCount: metrics?.length || 0,
// timeRange,
// sampleMetric: metrics?.[0] ? {
// id: metrics[0].id,
// created: metrics[0].created,
// timestamp: metrics[0].timestamp,
// server_id: metrics[0].server_id
// } : null
// });
if (!metrics?.length) {
console.log('❌ formatChartData: No metrics provided');
// console.log('❌ formatChartData: No metrics provided');
return [];
}
const filteredMetrics = filterMetricsByTimeRange(metrics, timeRange);
console.log('📊 formatChartData: After time filtering:', filteredMetrics?.length || 0, 'metrics');
// console.log('📊 formatChartData: After time filtering:', filteredMetrics?.length || 0, 'metrics');
if (!filteredMetrics.length) {
console.log('❌ formatChartData: No metrics after time filtering');
// console.log('❌ formatChartData: No metrics after time filtering');
return [];
}
@@ -213,7 +213,7 @@ export const formatChartData = (metrics: any[], timeRange: TimeRange) => {
? filteredMetrics.filter((_, index) => index % Math.ceil(filteredMetrics.length / maxDataPoints) === 0)
: filteredMetrics;
console.log('📊 formatChartData: After sampling:', sampledMetrics.length, 'metrics for display');
// console.log('📊 formatChartData: After sampling:', sampledMetrics.length, 'metrics for display');
const formattedData = sampledMetrics.map((metric) => {
const cpuUsage = typeof metric.cpu_usage === 'string' ?
@@ -269,6 +269,6 @@ export const formatChartData = (metrics: any[], timeRange: TimeRange) => {
};
});
console.log('✅ formatChartData: Final formatted data count:', formattedData.length);
// console.log('✅ formatChartData: Final formatted data count:', formattedData.length);
return formattedData;
};
@@ -7,7 +7,7 @@ import { formatChartData } from "../dataUtils";
type TimeRange = '60m' | '1d' | '7d' | '1m' | '3m';
export const useServerHistoryData = (serverId: string) => {
const [timeRange, setTimeRange] = useState<TimeRange>("1d");
const [timeRange, setTimeRange] = useState<TimeRange>("60m");
const {
data: metrics = [],