Disable the debug console logs for production
This commit is contained in:
@@ -11,19 +11,19 @@ const api = {
|
|||||||
* Handle API requests
|
* Handle API requests
|
||||||
*/
|
*/
|
||||||
async handleRequest(path, method, body) {
|
async handleRequest(path, method, body) {
|
||||||
console.log(`API request: ${method} ${path}`, body);
|
// console.log(`API request: ${method} ${path}`, body);
|
||||||
|
|
||||||
// Route to the appropriate handler
|
// Route to the appropriate handler
|
||||||
if (path === '/api/realtime') {
|
if (path === '/api/realtime') {
|
||||||
console.log("Routing to realtime handler");
|
// console.log("Routing to realtime handler");
|
||||||
return await realtime(body);
|
return await realtime(body);
|
||||||
} else if (path === '/api/settings' || path.startsWith('/api/settings/')) {
|
} else if (path === '/api/settings' || path.startsWith('/api/settings/')) {
|
||||||
console.log("Routing to settings handler");
|
// console.log("Routing to settings handler");
|
||||||
return await settingsApi(body, path);
|
return await settingsApi(body, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return 404 for unknown routes
|
// Return 404 for unknown routes
|
||||||
console.error(`Endpoint not found: ${path}`);
|
// console.error(`Endpoint not found: ${path}`);
|
||||||
return {
|
return {
|
||||||
status: 404,
|
status: 404,
|
||||||
json: {
|
json: {
|
||||||
@@ -40,7 +40,7 @@ const originalFetch = window.fetch;
|
|||||||
window.fetch = async (url, options = {}) => {
|
window.fetch = async (url, options = {}) => {
|
||||||
// Check if this is an API request to our mock endpoints
|
// Check if this is an API request to our mock endpoints
|
||||||
if (typeof url === 'string' && url.startsWith('/api/')) {
|
if (typeof url === 'string' && url.startsWith('/api/')) {
|
||||||
console.log('Intercepting API request:', url, options);
|
// console.log('Intercepting API request:', url, options);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let body = {};
|
let body = {};
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { testEmail } from './actions/testEmail';
|
|||||||
* Settings API handler
|
* Settings API handler
|
||||||
*/
|
*/
|
||||||
const settingsApi = async (body: any, path?: string) => {
|
const settingsApi = async (body: any, path?: string) => {
|
||||||
console.log('Settings API called with path:', path, 'body:', body);
|
// console.log('Settings API called with path:', path, 'body:', body);
|
||||||
|
|
||||||
// Handle test email endpoint specifically
|
// Handle test email endpoint specifically
|
||||||
if (path === '/api/settings/test/email') {
|
if (path === '/api/settings/test/email') {
|
||||||
@@ -18,7 +18,7 @@ const settingsApi = async (body: any, path?: string) => {
|
|||||||
|
|
||||||
// Handle regular settings API with action-based routing
|
// Handle regular settings API with action-based routing
|
||||||
const action = body?.action;
|
const action = body?.action;
|
||||||
console.log('Settings API called with action:', action, 'data:', body?.data);
|
// console.log('Settings API called with action:', action, 'data:', body?.data);
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'getSettings':
|
case 'getSettings':
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const Header = ({
|
|||||||
// Log avatar data for debugging
|
// Log avatar data for debugging
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentUser) {
|
if (currentUser) {
|
||||||
console.log("Avatar URL in Header:", currentUser.avatar);
|
// console.log("Avatar URL in Header:", currentUser.avatar);
|
||||||
}
|
}
|
||||||
}, [currentUser]);
|
}, [currentUser]);
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ export const Header = ({
|
|||||||
} else {
|
} else {
|
||||||
avatarUrl = currentUser.avatar;
|
avatarUrl = currentUser.avatar;
|
||||||
}
|
}
|
||||||
console.log("Final avatar URL:", avatarUrl);
|
// console.log("Final avatar URL:", avatarUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ export const ScheduleIncidentContent = () => {
|
|||||||
|
|
||||||
// Initialize maintenance notifications when the component mounts
|
// Initialize maintenance notifications when the component mounts
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("Initializing maintenance notifications");
|
// console.log("Initializing maintenance notifications");
|
||||||
initMaintenanceNotifications();
|
initMaintenanceNotifications();
|
||||||
|
|
||||||
// Clean up when the component unmounts
|
// Clean up when the component unmounts
|
||||||
return () => {
|
return () => {
|
||||||
console.log("Cleaning up maintenance notifications");
|
// console.log("Cleaning up maintenance notifications");
|
||||||
stopMaintenanceNotifications();
|
stopMaintenanceNotifications();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
@@ -43,7 +43,7 @@ export const ScheduleIncidentContent = () => {
|
|||||||
const handleMaintenanceCreated = () => {
|
const handleMaintenanceCreated = () => {
|
||||||
// Refresh data by incrementing the refresh trigger
|
// Refresh data by incrementing the refresh trigger
|
||||||
const newTriggerValue = refreshTrigger + 1;
|
const newTriggerValue = refreshTrigger + 1;
|
||||||
console.log("Maintenance created, refreshing data with new trigger value:", newTriggerValue);
|
// console.log("Maintenance created, refreshing data with new trigger value:", newTriggerValue);
|
||||||
setRefreshTrigger(newTriggerValue);
|
setRefreshTrigger(newTriggerValue);
|
||||||
|
|
||||||
// Show success toast
|
// Show success toast
|
||||||
@@ -56,7 +56,7 @@ export const ScheduleIncidentContent = () => {
|
|||||||
const handleIncidentCreated = () => {
|
const handleIncidentCreated = () => {
|
||||||
// Refresh data by incrementing the refresh trigger
|
// Refresh data by incrementing the refresh trigger
|
||||||
const newTriggerValue = incidentRefreshTrigger + 1;
|
const newTriggerValue = incidentRefreshTrigger + 1;
|
||||||
console.log("Incident created, refreshing data with new trigger value:", newTriggerValue);
|
// console.log("Incident created, refreshing data with new trigger value:", newTriggerValue);
|
||||||
setIncidentRefreshTrigger(newTriggerValue);
|
setIncidentRefreshTrigger(newTriggerValue);
|
||||||
|
|
||||||
// Show success toast
|
// Show success toast
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) =>
|
|||||||
const fetchIncidentData = useCallback(async (force = false) => {
|
const fetchIncidentData = useCallback(async (force = false) => {
|
||||||
// Skip if already fetching
|
// Skip if already fetching
|
||||||
if (isFetchingRef.current) {
|
if (isFetchingRef.current) {
|
||||||
console.log('Already fetching data, skipping additional request');
|
// console.log('Already fetching data, skipping additional request');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip if not forced and already initialized
|
// Skip if not forced and already initialized
|
||||||
if (initialized && !force) {
|
if (initialized && !force) {
|
||||||
console.log('Data already initialized and no force refresh, skipping fetch');
|
// console.log('Data already initialized and no force refresh, skipping fetch');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,22 +46,22 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) =>
|
|||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(`Fetching incident data (force=${force})`);
|
// console.log(`Fetching incident data (force=${force})`);
|
||||||
const allIncidents = await incidentService.getAllIncidents(force);
|
const allIncidents = await incidentService.getAllIncidents(force);
|
||||||
|
|
||||||
if (Array.isArray(allIncidents)) {
|
if (Array.isArray(allIncidents)) {
|
||||||
setIncidents(allIncidents);
|
setIncidents(allIncidents);
|
||||||
console.log(`Successfully set ${allIncidents.length} incidents to state`);
|
// console.log(`Successfully set ${allIncidents.length} incidents to state`);
|
||||||
} else {
|
} else {
|
||||||
setIncidents([]);
|
setIncidents([]);
|
||||||
console.warn('No incidents returned from service');
|
// console.warn('No incidents returned from service');
|
||||||
}
|
}
|
||||||
|
|
||||||
setInitialized(true);
|
setInitialized(true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setIsRefreshing(false);
|
setIsRefreshing(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching incident data:', error);
|
// console.error('Error fetching incident data:', error);
|
||||||
setError('Failed to load incident data. Please try again later.');
|
setError('Failed to load incident data. Please try again later.');
|
||||||
setIncidents([]);
|
setIncidents([]);
|
||||||
setInitialized(true);
|
setInitialized(true);
|
||||||
@@ -79,7 +79,7 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) =>
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Skip if the refresh trigger hasn't changed (prevents duplicate effect calls)
|
// Skip if the refresh trigger hasn't changed (prevents duplicate effect calls)
|
||||||
if (refreshTrigger === lastRefreshTriggerRef.current && initialized) {
|
if (refreshTrigger === lastRefreshTriggerRef.current && initialized) {
|
||||||
console.log('Refresh trigger unchanged, skipping fetch');
|
// console.log('Refresh trigger unchanged, skipping fetch');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) =>
|
|||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
let isMounted = true;
|
let isMounted = true;
|
||||||
|
|
||||||
console.log(`useIncidentData effect running, refreshTrigger: ${refreshTrigger}`);
|
// console.log(`useIncidentData effect running, refreshTrigger: ${refreshTrigger}`);
|
||||||
|
|
||||||
// Use a longer delay to ensure we don't trigger too many API calls
|
// Use a longer delay to ensure we don't trigger too many API calls
|
||||||
const fetchTimer = setTimeout(() => {
|
const fetchTimer = setTimeout(() => {
|
||||||
@@ -101,7 +101,7 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) =>
|
|||||||
|
|
||||||
// Cleanup function to abort any in-flight requests and clear timers
|
// Cleanup function to abort any in-flight requests and clear timers
|
||||||
return () => {
|
return () => {
|
||||||
console.log('Cleaning up incident data fetch effect');
|
// console.log('Cleaning up incident data fetch effect');
|
||||||
isMounted = false;
|
isMounted = false;
|
||||||
clearTimeout(fetchTimer);
|
clearTimeout(fetchTimer);
|
||||||
abortController.abort();
|
abortController.abort();
|
||||||
@@ -112,7 +112,7 @@ export const useIncidentData = ({ refreshTrigger = 0 }: UseIncidentDataProps) =>
|
|||||||
const incidentData = useMemo(() => {
|
const incidentData = useMemo(() => {
|
||||||
if (!initialized || incidents.length === 0) return [];
|
if (!initialized || incidents.length === 0) return [];
|
||||||
|
|
||||||
console.log(`Filtering incidents by: ${filter}`);
|
// console.log(`Filtering incidents by: ${filter}`);
|
||||||
|
|
||||||
if (filter === "unresolved") {
|
if (filter === "unresolved") {
|
||||||
return incidents.filter(item => {
|
return incidents.filter(item => {
|
||||||
|
|||||||
+20
-20
@@ -27,7 +27,7 @@ export const MaintenanceNotificationSettingsField = () => {
|
|||||||
try {
|
try {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const channels = await alertConfigService.getAlertConfigurations();
|
const channels = await alertConfigService.getAlertConfigurations();
|
||||||
console.log("Fetched notification channels for form:", channels);
|
// console.log("Fetched notification channels for form:", channels);
|
||||||
|
|
||||||
// Only show enabled channels
|
// Only show enabled channels
|
||||||
const enabledChannels = channels.filter(channel => channel.enabled);
|
const enabledChannels = channels.filter(channel => channel.enabled);
|
||||||
@@ -38,18 +38,18 @@ export const MaintenanceNotificationSettingsField = () => {
|
|||||||
const currentChannel = getValues('notification_channel_id');
|
const currentChannel = getValues('notification_channel_id');
|
||||||
const shouldNotify = getValues('notify_subscribers');
|
const shouldNotify = getValues('notify_subscribers');
|
||||||
|
|
||||||
console.log("Current notification values:", {
|
// console.log("Current notification values:", {
|
||||||
currentChannel,
|
// currentChannel,
|
||||||
shouldNotify,
|
// shouldNotify,
|
||||||
availableChannels: enabledChannels.length
|
// availableChannels: enabledChannels.length
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (shouldNotify && (!currentChannel || currentChannel === 'none') && enabledChannels.length > 0) {
|
if (shouldNotify && (!currentChannel || currentChannel === 'none') && enabledChannels.length > 0) {
|
||||||
console.log("Setting default notification channel:", enabledChannels[0].id);
|
// console.log("Setting default notification channel:", enabledChannels[0].id);
|
||||||
setValue('notification_channel_id', enabledChannels[0].id);
|
setValue('notification_channel_id', enabledChannels[0].id);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching notification channels:', error);
|
// console.error('Error fetching notification channels:', error);
|
||||||
toast({
|
toast({
|
||||||
title: t('error'),
|
title: t('error'),
|
||||||
description: t('errorFetchingNotificationChannels'),
|
description: t('errorFetchingNotificationChannels'),
|
||||||
@@ -64,12 +64,12 @@ export const MaintenanceNotificationSettingsField = () => {
|
|||||||
}, [t, toast, setValue, getValues]);
|
}, [t, toast, setValue, getValues]);
|
||||||
|
|
||||||
// Log value changes for debugging
|
// Log value changes for debugging
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
console.log("Current notification settings:", {
|
// console.log("Current notification settings:", {
|
||||||
channel_id: getValues('notification_channel_id'),
|
// channel_id: getValues('notification_channel_id'),
|
||||||
notify: notifySubscribers
|
// notify: notifySubscribers
|
||||||
});
|
// });
|
||||||
}, [notifySubscribers, notificationChannelId, getValues]);
|
// }, [notifySubscribers, notificationChannelId, getValues]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
@@ -98,7 +98,7 @@ export const MaintenanceNotificationSettingsField = () => {
|
|||||||
checked={field.value}
|
checked={field.value}
|
||||||
onCheckedChange={(checked) => {
|
onCheckedChange={(checked) => {
|
||||||
field.onChange(checked);
|
field.onChange(checked);
|
||||||
console.log("Notification toggle changed to:", checked);
|
// console.log("Notification toggle changed to:", checked);
|
||||||
// If notifications are disabled, also clear the notification channel
|
// If notifications are disabled, also clear the notification channel
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
setValue('notification_channel_id', '');
|
setValue('notification_channel_id', '');
|
||||||
@@ -120,10 +120,10 @@ export const MaintenanceNotificationSettingsField = () => {
|
|||||||
// Make sure to handle both empty string and "none" as special cases
|
// Make sure to handle both empty string and "none" as special cases
|
||||||
const displayValue = field.value || "";
|
const displayValue = field.value || "";
|
||||||
|
|
||||||
console.log("Rendering notification channel field with value:", {
|
// console.log("Rendering notification channel field with value:", {
|
||||||
fieldValue: field.value,
|
// fieldValue: field.value,
|
||||||
displayValue
|
// displayValue
|
||||||
});
|
// });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
@@ -135,7 +135,7 @@ export const MaintenanceNotificationSettingsField = () => {
|
|||||||
<Select
|
<Select
|
||||||
value={displayValue}
|
value={displayValue}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
console.log("Setting notification channel to:", value);
|
// console.log("Setting notification channel to:", value);
|
||||||
field.onChange(value === "none" ? "" : value);
|
field.onChange(value === "none" ? "" : value);
|
||||||
}}
|
}}
|
||||||
disabled={!notifySubscribers}
|
disabled={!notifySubscribers}
|
||||||
|
|||||||
+10
-10
@@ -31,17 +31,17 @@ export const AssignedUsersField = () => {
|
|||||||
// Ensure assigned_users is initialized as an array
|
// Ensure assigned_users is initialized as an array
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentValue = form.getValues('assigned_users');
|
const currentValue = form.getValues('assigned_users');
|
||||||
console.log("Initial assigned_users value:", currentValue);
|
// console.log("Initial assigned_users value:", currentValue);
|
||||||
|
|
||||||
// Initialize as empty array if no value or invalid value
|
// Initialize as empty array if no value or invalid value
|
||||||
if (!currentValue || !Array.isArray(currentValue)) {
|
if (!currentValue || !Array.isArray(currentValue)) {
|
||||||
console.log("Initializing assigned_users as empty array");
|
// console.log("Initializing assigned_users as empty array");
|
||||||
form.setValue('assigned_users', [], { shouldValidate: false, shouldDirty: true });
|
form.setValue('assigned_users', [], { shouldValidate: false, shouldDirty: true });
|
||||||
}
|
}
|
||||||
}, [form]);
|
}, [form]);
|
||||||
|
|
||||||
console.log("Current form values:", form.getValues());
|
//console.log("Current form values:", form.getValues());
|
||||||
console.log("Current assigned_users:", form.getValues('assigned_users'));
|
//console.log("Current assigned_users:", form.getValues('assigned_users'));
|
||||||
|
|
||||||
// Fetch users for the assignment dropdown
|
// Fetch users for the assignment dropdown
|
||||||
const { data: users = [], isLoading } = useQuery({
|
const { data: users = [], isLoading } = useQuery({
|
||||||
@@ -49,10 +49,10 @@ export const AssignedUsersField = () => {
|
|||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
try {
|
try {
|
||||||
const usersList = await userService.getUsers();
|
const usersList = await userService.getUsers();
|
||||||
console.log("Fetched users for assignment:", usersList);
|
// console.log("Fetched users for assignment:", usersList);
|
||||||
return Array.isArray(usersList) ? usersList : [];
|
return Array.isArray(usersList) ? usersList : [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch users:", error);
|
// console.error("Failed to fetch users:", error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -64,7 +64,7 @@ export const AssignedUsersField = () => {
|
|||||||
? form.watch('assigned_users')
|
? form.watch('assigned_users')
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
console.log("Selected user IDs:", selectedUserIds);
|
// console.log("Selected user IDs:", selectedUserIds);
|
||||||
|
|
||||||
// Function to add a user
|
// Function to add a user
|
||||||
const addUser = (userId: string) => {
|
const addUser = (userId: string) => {
|
||||||
@@ -73,7 +73,7 @@ export const AssignedUsersField = () => {
|
|||||||
: [];
|
: [];
|
||||||
|
|
||||||
if (!currentValues.includes(userId)) {
|
if (!currentValues.includes(userId)) {
|
||||||
console.log("Adding user:", userId);
|
// console.log("Adding user:", userId);
|
||||||
form.setValue('assigned_users', [...currentValues, userId], { shouldValidate: true, shouldDirty: true });
|
form.setValue('assigned_users', [...currentValues, userId], { shouldValidate: true, shouldDirty: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -84,7 +84,7 @@ export const AssignedUsersField = () => {
|
|||||||
? [...form.getValues('assigned_users')]
|
? [...form.getValues('assigned_users')]
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
console.log("Removing user:", userId);
|
// console.log("Removing user:", userId);
|
||||||
form.setValue(
|
form.setValue(
|
||||||
'assigned_users',
|
'assigned_users',
|
||||||
currentValues.filter(id => id !== userId),
|
currentValues.filter(id => id !== userId),
|
||||||
@@ -94,7 +94,7 @@ export const AssignedUsersField = () => {
|
|||||||
|
|
||||||
// Get selected users data
|
// Get selected users data
|
||||||
const selectedUsers = users.filter(user => selectedUserIds.includes(user.id));
|
const selectedUsers = users.filter(user => selectedUserIds.includes(user.id));
|
||||||
console.log("Matched selected users:", selectedUsers);
|
// console.log("Matched selected users:", selectedUsers);
|
||||||
|
|
||||||
// Function to get user initials from name
|
// Function to get user initials from name
|
||||||
const getUserInitials = (user: any): string => {
|
const getUserInitials = (user: any): string => {
|
||||||
|
|||||||
+6
-6
@@ -22,12 +22,12 @@ export const useRealTimeUpdates = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!serviceId) return;
|
if (!serviceId) return;
|
||||||
|
|
||||||
console.log(`Setting up real-time updates for service: ${serviceId}`);
|
// console.log(`Setting up real-time updates for service: ${serviceId}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Subscribe to the service record for real-time updates
|
// Subscribe to the service record for real-time updates
|
||||||
const subscription = pb.collection('services').subscribe(serviceId, function(e) {
|
const subscription = pb.collection('services').subscribe(serviceId, function(e) {
|
||||||
console.log("Service updated:", e.record);
|
// console.log("Service updated:", e.record);
|
||||||
|
|
||||||
// Update our local state with the new data
|
// Update our local state with the new data
|
||||||
if (e.record) {
|
if (e.record) {
|
||||||
@@ -47,7 +47,7 @@ export const useRealTimeUpdates = ({
|
|||||||
// Subscribe to uptime data updates
|
// Subscribe to uptime data updates
|
||||||
const uptimeSubscription = pb.collection('uptime_data').subscribe('*', function(e) {
|
const uptimeSubscription = pb.collection('uptime_data').subscribe('*', function(e) {
|
||||||
if (e.record && e.record.service_id === serviceId) {
|
if (e.record && e.record.service_id === serviceId) {
|
||||||
console.log("New uptime data:", e.record);
|
// console.log("New uptime data:", e.record);
|
||||||
|
|
||||||
// Add the new uptime data to our list if it's within the selected date range
|
// Add the new uptime data to our list if it's within the selected date range
|
||||||
const timestamp = new Date(e.record.timestamp);
|
const timestamp = new Date(e.record.timestamp);
|
||||||
@@ -73,16 +73,16 @@ export const useRealTimeUpdates = ({
|
|||||||
|
|
||||||
// Clean up the subscriptions
|
// Clean up the subscriptions
|
||||||
return () => {
|
return () => {
|
||||||
console.log(`Cleaning up subscriptions for service: ${serviceId}`);
|
// console.log(`Cleaning up subscriptions for service: ${serviceId}`);
|
||||||
try {
|
try {
|
||||||
pb.collection('services').unsubscribe(serviceId);
|
pb.collection('services').unsubscribe(serviceId);
|
||||||
pb.collection('uptime_data').unsubscribe('*');
|
pb.collection('uptime_data').unsubscribe('*');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error cleaning up subscriptions:", error);
|
// console.error("Error cleaning up subscriptions:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error setting up real-time updates:", error);
|
// console.error("Error setting up real-time updates:", error);
|
||||||
}
|
}
|
||||||
}, [serviceId, startDate, endDate, setService, setUptimeData]);
|
}, [serviceId, startDate, endDate, setService, setUptimeData]);
|
||||||
};
|
};
|
||||||
+18
-18
@@ -38,7 +38,7 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
description: `Service status changed to ${newStatus}`,
|
description: `Service status changed to ${newStatus}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to update service status:", error);
|
// console.error("Failed to update service status:", error);
|
||||||
setService(prevService => prevService);
|
setService(prevService => prevService);
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
@@ -52,12 +52,12 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
const fetchUptimeData = async (serviceId: string, start: Date, end: Date, selectedRange?: DateRangeOption | string, regionalAgent?: string) => {
|
const fetchUptimeData = async (serviceId: string, start: Date, end: Date, selectedRange?: DateRangeOption | string, regionalAgent?: string) => {
|
||||||
try {
|
try {
|
||||||
if (!service) {
|
if (!service) {
|
||||||
console.log('No service data available for uptime fetch');
|
// console.log('No service data available for uptime fetch');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentAgent = regionalAgent || selectedRegionalAgent;
|
const currentAgent = regionalAgent || selectedRegionalAgent;
|
||||||
console.log(`Fetching uptime data: ${start.toISOString()} to ${end.toISOString()} for range: ${selectedRange}, service type: ${service.type}, regional agent: ${currentAgent}`);
|
// console.log(`Fetching uptime data: ${start.toISOString()} to ${end.toISOString()} for range: ${selectedRange}, service type: ${service.type}, regional agent: ${currentAgent}`);
|
||||||
|
|
||||||
// Clear existing data immediately when switching agents
|
// Clear existing data immediately when switching agents
|
||||||
setUptimeData([]);
|
setUptimeData([]);
|
||||||
@@ -70,17 +70,17 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
limit = 400;
|
limit = 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Using limit ${limit} for range ${selectedRange}`);
|
// console.log(`Using limit ${limit} for range ${selectedRange}`);
|
||||||
|
|
||||||
let history: UptimeData[] = [];
|
let history: UptimeData[] = [];
|
||||||
|
|
||||||
if (currentAgent === "all") {
|
if (currentAgent === "all") {
|
||||||
// Fetch data from all sources (default + all online regional agents)
|
// Fetch data from all sources (default + all online regional agents)
|
||||||
console.log(`Fetching data from all monitoring sources`);
|
// console.log(`Fetching data from all monitoring sources`);
|
||||||
|
|
||||||
// Fetch default monitoring data
|
// Fetch default monitoring data
|
||||||
const defaultData = await uptimeService.getUptimeHistory(serviceId, limit, start, end, service.type);
|
const defaultData = await uptimeService.getUptimeHistory(serviceId, limit, start, end, service.type);
|
||||||
console.log(`Retrieved ${defaultData.length} default monitoring records`);
|
// console.log(`Retrieved ${defaultData.length} default monitoring records`);
|
||||||
|
|
||||||
// Mark default data with source identifier
|
// Mark default data with source identifier
|
||||||
const markedDefaultData = defaultData.map(record => ({
|
const markedDefaultData = defaultData.map(record => ({
|
||||||
@@ -100,7 +100,7 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
const regionalData = await uptimeService.getUptimeHistoryByRegionalAgent(
|
const regionalData = await uptimeService.getUptimeHistoryByRegionalAgent(
|
||||||
serviceId, limit, start, end, service.type, agent.region_name, agent.agent_id
|
serviceId, limit, start, end, service.type, agent.region_name, agent.agent_id
|
||||||
);
|
);
|
||||||
console.log(`Retrieved ${regionalData.length} records from ${agent.region_name}`);
|
// console.log(`Retrieved ${regionalData.length} records from ${agent.region_name}`);
|
||||||
|
|
||||||
// Mark regional data with source identifier
|
// Mark regional data with source identifier
|
||||||
const markedRegionalData = regionalData.map(record => ({
|
const markedRegionalData = regionalData.map(record => ({
|
||||||
@@ -112,18 +112,18 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
|
|
||||||
history = [...history, ...markedRegionalData];
|
history = [...history, ...markedRegionalData];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error fetching data from ${agent.region_name}:`, error);
|
// console.error(`Error fetching data from ${agent.region_name}:`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Total combined records: ${history.length}`);
|
// console.log(`Total combined records: ${history.length}`);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Fetch regional agent specific data
|
// Fetch regional agent specific data
|
||||||
const [regionName, agentId] = currentAgent.split("|");
|
const [regionName, agentId] = currentAgent.split("|");
|
||||||
console.log(`Fetching regional agent data for region: ${regionName}, agent: ${agentId} from ${service.type} collection`);
|
// console.log(`Fetching regional agent data for region: ${regionName}, agent: ${agentId} from ${service.type} collection`);
|
||||||
history = await uptimeService.getUptimeHistoryByRegionalAgent(serviceId, limit, start, end, service.type, regionName, agentId);
|
history = await uptimeService.getUptimeHistoryByRegionalAgent(serviceId, limit, start, end, service.type, regionName, agentId);
|
||||||
console.log(`Retrieved ${history.length} regional monitoring records`);
|
// console.log(`Retrieved ${history.length} regional monitoring records`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort by timestamp (newest first)
|
// Sort by timestamp (newest first)
|
||||||
@@ -131,11 +131,11 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`Final dataset: ${filteredHistory.length} records for ${currentAgent === "all" ? "all sources" : "regional"} monitoring`);
|
//console.log(`Final dataset: ${filteredHistory.length} records for ${currentAgent === "all" ? "all sources" : "regional"} monitoring`);
|
||||||
setUptimeData(filteredHistory);
|
setUptimeData(filteredHistory);
|
||||||
return filteredHistory;
|
return filteredHistory;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching uptime data:", error);
|
// console.error("Error fetching uptime data:", error);
|
||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
@@ -146,7 +146,7 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRegionalAgentChange = (agent: string) => {
|
const handleRegionalAgentChange = (agent: string) => {
|
||||||
console.log(`Regional agent changed from ${selectedRegionalAgent} to: ${agent}`);
|
// console.log(`Regional agent changed from ${selectedRegionalAgent} to: ${agent}`);
|
||||||
|
|
||||||
// Clear data immediately when switching
|
// Clear data immediately when switching
|
||||||
setUptimeData([]);
|
setUptimeData([]);
|
||||||
@@ -154,7 +154,7 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
|
|
||||||
// Refetch data with new agent selection
|
// Refetch data with new agent selection
|
||||||
if (serviceId && !isLoading && service) {
|
if (serviceId && !isLoading && service) {
|
||||||
console.log(`Refetching data for new agent: ${agent}`);
|
// console.log(`Refetching data for new agent: ${agent}`);
|
||||||
fetchUptimeData(serviceId, startDate, endDate, '24h', agent);
|
fetchUptimeData(serviceId, startDate, endDate, '24h', agent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -196,13 +196,13 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
alerts: serviceData.alerts || "unmuted"
|
alerts: serviceData.alerts || "unmuted"
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(`Loaded service: ${formattedService.name} (${formattedService.type})`);
|
// console.log(`Loaded service: ${formattedService.name} (${formattedService.type})`);
|
||||||
setService(formattedService);
|
setService(formattedService);
|
||||||
|
|
||||||
// Small delay to ensure state is updated before fetching uptime data
|
// Small delay to ensure state is updated before fetching uptime data
|
||||||
await new Promise(resolve => setTimeout(resolve, 100));
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching service:", error);
|
// console.error("Error fetching service:", error);
|
||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
@@ -220,7 +220,7 @@ export const useServiceData = (serviceId: string | undefined, startDate: Date, e
|
|||||||
// Update data when date range changes or when service is loaded
|
// Update data when date range changes or when service is loaded
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (serviceId && !isLoading && service) {
|
if (serviceId && !isLoading && service) {
|
||||||
console.log(`Date range changed or service loaded, refetching data for ${serviceId}: ${startDate.toISOString()} to ${endDate.toISOString()}`);
|
// console.log(`Date range changed or service loaded, refetching data for ${serviceId}: ${startDate.toISOString()} to ${endDate.toISOString()}`);
|
||||||
fetchUptimeData(serviceId, startDate, endDate, '24h', selectedRegionalAgent);
|
fetchUptimeData(serviceId, startDate, endDate, '24h', selectedRegionalAgent);
|
||||||
}
|
}
|
||||||
}, [startDate, endDate, serviceId, isLoading, service, selectedRegionalAgent, regionalAgents]);
|
}, [startDate, endDate, serviceId, isLoading, service, selectedRegionalAgent, regionalAgents]);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export function ServiceMonitoringButton({ service, onStatusChange }: ServiceMoni
|
|||||||
|
|
||||||
if (isMonitoring) {
|
if (isMonitoring) {
|
||||||
// Pause monitoring
|
// Pause monitoring
|
||||||
console.log(`Pausing monitoring for service ${service.id} (${service.name})`);
|
// console.log(`Pausing monitoring for service ${service.id} (${service.name})`);
|
||||||
await serviceService.pauseMonitoring(service.id);
|
await serviceService.pauseMonitoring(service.id);
|
||||||
setIsMonitoring(false);
|
setIsMonitoring(false);
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ export function ServiceMonitoringButton({ service, onStatusChange }: ServiceMoni
|
|||||||
|
|
||||||
// Send notification for paused status (only here, not in pauseMonitoring.ts)
|
// Send notification for paused status (only here, not in pauseMonitoring.ts)
|
||||||
if (service.alerts !== "muted") {
|
if (service.alerts !== "muted") {
|
||||||
console.log("Sending pause notification from UI component");
|
// console.log("Sending pause notification from UI component");
|
||||||
// IMPORTANT: Direct call to the notification service to ensure a message is sent
|
// IMPORTANT: Direct call to the notification service to ensure a message is sent
|
||||||
await notificationService.sendNotification({
|
await notificationService.sendNotification({
|
||||||
service: service,
|
service: service,
|
||||||
@@ -51,7 +51,7 @@ export function ServiceMonitoringButton({ service, onStatusChange }: ServiceMoni
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Start/resume monitoring
|
// Start/resume monitoring
|
||||||
console.log(`Starting monitoring for service ${service.id} (${service.name})`);
|
// console.log(`Starting monitoring for service ${service.id} (${service.name})`);
|
||||||
|
|
||||||
// First ensure we update the status in the database to not be paused anymore
|
// First ensure we update the status in the database to not be paused anymore
|
||||||
await serviceService.resumeMonitoring(service.id);
|
await serviceService.resumeMonitoring(service.id);
|
||||||
@@ -66,7 +66,7 @@ export function ServiceMonitoringButton({ service, onStatusChange }: ServiceMoni
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error toggling monitoring:", error);
|
// console.error("Error toggling monitoring:", error);
|
||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export const UptimeBar = ({ uptime, status, serviceId, interval, serviceType }:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('UptimeBar rendering consolidated items:', consolidatedItems.length);
|
// console.log('UptimeBar rendering consolidated items:', consolidatedItems.length);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-52">
|
<div className="w-52">
|
||||||
@@ -78,9 +78,9 @@ export const UptimeBar = ({ uptime, status, serviceId, interval, serviceType }:
|
|||||||
statuses.includes('paused') ? 'paused' : 'unknown';
|
statuses.includes('paused') ? 'paused' : 'unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Bar ${index} - Timestamp: ${slot.timestamp}, Items: ${slot.items.length}, Primary Status: ${primaryStatus}, Has Valid Data: ${hasValidData}`);
|
// console.log(`Bar ${index} - Timestamp: ${slot.timestamp}, Items: ${slot.items.length}, Primary Status: ${primaryStatus}, Has Valid Data: ${hasValidData}`);
|
||||||
slot.items.forEach((item, itemIndex) => {
|
slot.items.forEach((item, itemIndex) => {
|
||||||
console.log(` Item ${itemIndex}: Source=${item.source}, Status=${item.status}, ResponseTime=${item.responseTime}, IsDefault=${item.isDefault}`);
|
// console.log(` Item ${itemIndex}: Source=${item.source}, Status=${item.status}, ResponseTime=${item.responseTime}, IsDefault=${item.isDefault}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -46,23 +46,23 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
queryKey: ['consolidatedUptimeHistory', serviceId, serviceType],
|
queryKey: ['consolidatedUptimeHistory', serviceId, serviceType],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (!serviceId) {
|
if (!serviceId) {
|
||||||
console.log('No serviceId provided, skipping fetch');
|
// console.log('No serviceId provided, skipping fetch');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
console.log(`Fetching consolidated uptime data for service ${serviceId} of type ${serviceType}`);
|
// console.log(`Fetching consolidated uptime data for service ${serviceId} of type ${serviceType}`);
|
||||||
|
|
||||||
// Get ALL uptime history data - this should include both default and regional data
|
// Get ALL uptime history data - this should include both default and regional data
|
||||||
const rawData = await uptimeService.getUptimeHistory(serviceId, 100, undefined, undefined, serviceType);
|
const rawData = await uptimeService.getUptimeHistory(serviceId, 100, undefined, undefined, serviceType);
|
||||||
|
|
||||||
console.log(`Retrieved ${rawData.length} total records for service ${serviceId}`);
|
// console.log(`Retrieved ${rawData.length} total records for service ${serviceId}`);
|
||||||
console.log('Raw data sample:', rawData.slice(0, 5).map(d => ({
|
// console.log('Raw data sample:', rawData.slice(0, 5).map(d => ({
|
||||||
timestamp: d.timestamp,
|
// timestamp: d.timestamp,
|
||||||
region_name: d.region_name,
|
// region_name: d.region_name,
|
||||||
agent_id: d.agent_id,
|
// agent_id: d.agent_id,
|
||||||
status: d.status,
|
// status: d.status,
|
||||||
service_id: d.service_id,
|
// service_id: d.service_id,
|
||||||
response_time: d.responseTime
|
// response_time: d.responseTime
|
||||||
})));
|
// })));
|
||||||
|
|
||||||
return rawData;
|
return rawData;
|
||||||
},
|
},
|
||||||
@@ -78,7 +78,7 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
const processConsolidatedData = (data: UptimeData[]): ConsolidatedTimeSlot[] => {
|
const processConsolidatedData = (data: UptimeData[]): ConsolidatedTimeSlot[] => {
|
||||||
if (!data || data.length === 0) return [];
|
if (!data || data.length === 0) return [];
|
||||||
|
|
||||||
console.log(`Processing ${data.length} uptime records for consolidation`);
|
// console.log(`Processing ${data.length} uptime records for consolidation`);
|
||||||
|
|
||||||
// Create a map to group records by normalized timestamp (minute precision)
|
// Create a map to group records by normalized timestamp (minute precision)
|
||||||
const timeSlotMap = new Map<string, Array<UptimeData & { source: string; isDefault: boolean }>>();
|
const timeSlotMap = new Map<string, Array<UptimeData & { source: string; isDefault: boolean }>>();
|
||||||
@@ -99,17 +99,17 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
// Regional monitoring data
|
// Regional monitoring data
|
||||||
sourceName = `${regionName} (Agent ${agentId})`;
|
sourceName = `${regionName} (Agent ${agentId})`;
|
||||||
isDefault = false;
|
isDefault = false;
|
||||||
console.log(`Found regional data: ${sourceName} for normalized timestamp ${normalizedTimestamp}`);
|
// console.log(`Found regional data: ${sourceName} for normalized timestamp ${normalizedTimestamp}`);
|
||||||
} else if (agentId && !regionName) {
|
} else if (agentId && !regionName) {
|
||||||
// Default monitoring with specific agent
|
// Default monitoring with specific agent
|
||||||
sourceName = `Default (Agent ${agentId})`;
|
sourceName = `Default (Agent ${agentId})`;
|
||||||
isDefault = true;
|
isDefault = true;
|
||||||
console.log(`Found default monitoring: ${sourceName} for normalized timestamp ${normalizedTimestamp}`);
|
// console.log(`Found default monitoring: ${sourceName} for normalized timestamp ${normalizedTimestamp}`);
|
||||||
} else {
|
} else {
|
||||||
// Default monitoring fallback
|
// Default monitoring fallback
|
||||||
sourceName = 'Default System Check (Agent 1)';
|
sourceName = 'Default System Check (Agent 1)';
|
||||||
isDefault = true;
|
isDefault = true;
|
||||||
console.log(`Using fallback default monitoring for normalized timestamp ${normalizedTimestamp}`);
|
// console.log(`Using fallback default monitoring for normalized timestamp ${normalizedTimestamp}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get or create the array for this normalized timestamp
|
// Get or create the array for this normalized timestamp
|
||||||
@@ -130,9 +130,9 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
isDefault
|
isDefault
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Added record to normalized timestamp ${normalizedTimestamp}: Source=${sourceName}, Status=${record.status}, IsDefault=${isDefault}, ResponseTime=${record.responseTime}ms`);
|
// console.log(`Added record to normalized timestamp ${normalizedTimestamp}: Source=${sourceName}, Status=${record.status}, IsDefault=${isDefault}, ResponseTime=${record.responseTime}ms`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`Skipping duplicate record for source ${sourceName} at timestamp ${normalizedTimestamp}`);
|
// console.log(`Skipping duplicate record for source ${sourceName} at timestamp ${normalizedTimestamp}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -150,13 +150,13 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
|
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
|
||||||
.slice(0, 20); // Take the most recent 20 time slots
|
.slice(0, 20); // Take the most recent 20 time slots
|
||||||
|
|
||||||
console.log(`Created ${consolidatedTimeline.length} consolidated time slots with normalized timestamps`);
|
// console.log(`Created ${consolidatedTimeline.length} consolidated time slots with normalized timestamps`);
|
||||||
consolidatedTimeline.forEach((slot, index) => {
|
// consolidatedTimeline.forEach((slot, index) => {
|
||||||
console.log(`Slot ${index} - Normalized Timestamp: ${slot.timestamp}, Items: ${slot.items.length}`);
|
// console.log(`Slot ${index} - Normalized Timestamp: ${slot.timestamp}, Items: ${slot.items.length}`);
|
||||||
slot.items.forEach((item, itemIndex) => {
|
// slot.items.forEach((item, itemIndex) => {
|
||||||
console.log(` Item ${itemIndex}: Source=${item.source}, Status=${item.status}, ResponseTime=${item.responseTime}ms, IsDefault=${item.isDefault}`);
|
// console.log(` Item ${itemIndex}: Source=${item.source}, Status=${item.status}, ResponseTime=${item.responseTime}ms, IsDefault=${item.isDefault}`);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
return consolidatedTimeline;
|
return consolidatedTimeline;
|
||||||
};
|
};
|
||||||
@@ -164,12 +164,12 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
// Update consolidated items when data changes
|
// Update consolidated items when data changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (uptimeData && uptimeData.length > 0) {
|
if (uptimeData && uptimeData.length > 0) {
|
||||||
console.log(`Processing consolidated uptime data for service ${serviceId}`);
|
// console.log(`Processing consolidated uptime data for service ${serviceId}`);
|
||||||
const processedData = processConsolidatedData(uptimeData);
|
const processedData = processConsolidatedData(uptimeData);
|
||||||
|
|
||||||
// If service is currently paused, override ONLY the latest (first) bar with paused status
|
// If service is currently paused, override ONLY the latest (first) bar with paused status
|
||||||
if (status === "paused" && processedData.length > 0) {
|
if (status === "paused" && processedData.length > 0) {
|
||||||
console.log(`Service ${serviceId} is paused, overriding latest bar with paused status`);
|
// console.log(`Service ${serviceId} is paused, overriding latest bar with paused status`);
|
||||||
|
|
||||||
// Create a paused entry for the latest timestamp
|
// Create a paused entry for the latest timestamp
|
||||||
const latestTimestamp = new Date();
|
const latestTimestamp = new Date();
|
||||||
@@ -191,11 +191,11 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
|
|
||||||
// Replace the first item with paused status, keep the rest as historical data
|
// Replace the first item with paused status, keep the rest as historical data
|
||||||
const updatedData = [pausedSlot, ...processedData.slice(0, 19)];
|
const updatedData = [pausedSlot, ...processedData.slice(0, 19)];
|
||||||
console.log(`Updated data with paused latest bar, total bars: ${updatedData.length}`);
|
// console.log(`Updated data with paused latest bar, total bars: ${updatedData.length}`);
|
||||||
setConsolidatedItems(updatedData);
|
setConsolidatedItems(updatedData);
|
||||||
} else {
|
} else {
|
||||||
// Service is active (up/down/warning) - merge real data with any existing paused bars
|
// Service is active (up/down/warning) - merge real data with any existing paused bars
|
||||||
console.log(`Service ${serviceId} is active with status: ${status}, merging with existing paused bars`);
|
// console.log(`Service ${serviceId} is active with status: ${status}, merging with existing paused bars`);
|
||||||
|
|
||||||
// Get existing paused bars from current state
|
// Get existing paused bars from current state
|
||||||
const existingPausedBars = consolidatedItems.filter(slot =>
|
const existingPausedBars = consolidatedItems.filter(slot =>
|
||||||
@@ -213,7 +213,7 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
const hasConflict = processedData.some(slot => slot.timestamp === pausedSlot.timestamp);
|
const hasConflict = processedData.some(slot => slot.timestamp === pausedSlot.timestamp);
|
||||||
if (!hasConflict) {
|
if (!hasConflict) {
|
||||||
mergedData.push(pausedSlot);
|
mergedData.push(pausedSlot);
|
||||||
console.log(`Preserved paused bar at timestamp: ${pausedSlot.timestamp}`);
|
// console.log(`Preserved paused bar at timestamp: ${pausedSlot.timestamp}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -222,12 +222,12 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
|
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
|
||||||
.slice(0, 20);
|
.slice(0, 20);
|
||||||
|
|
||||||
console.log(`Final merged data has ${finalData.length} slots`);
|
// console.log(`Final merged data has ${finalData.length} slots`);
|
||||||
setConsolidatedItems(finalData);
|
setConsolidatedItems(finalData);
|
||||||
}
|
}
|
||||||
} else if (!serviceId || (uptimeData && uptimeData.length === 0)) {
|
} else if (!serviceId || (uptimeData && uptimeData.length === 0)) {
|
||||||
// Generate placeholder data when no real data is available
|
// Generate placeholder data when no real data is available
|
||||||
console.log(`No uptime data available for service ${serviceId}, generating placeholder with status: ${status}`);
|
// console.log(`No uptime data available for service ${serviceId}, generating placeholder with status: ${status}`);
|
||||||
|
|
||||||
// Use the actual service status for placeholder data
|
// Use the actual service status for placeholder data
|
||||||
const statusValue = status === "paused" ? "paused" :
|
const statusValue = status === "paused" ? "paused" :
|
||||||
@@ -252,7 +252,7 @@ export const useConsolidatedUptimeData = ({ serviceId, serviceType, status, inte
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Generated ${placeholderHistory.length} placeholder slots with status: ${statusValue}`);
|
// console.log(`Generated ${placeholderHistory.length} placeholder slots with status: ${statusValue}`);
|
||||||
setConsolidatedItems(placeholderHistory);
|
setConsolidatedItems(placeholderHistory);
|
||||||
}
|
}
|
||||||
}, [uptimeData, serviceId, status, interval, consolidatedItems]);
|
}, [uptimeData, serviceId, status, interval, consolidatedItems]);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export function useServiceActions(initialServices: Service[]) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleViewDetail = (service: Service) => {
|
const handleViewDetail = (service: Service) => {
|
||||||
console.log(`Navigating to service detail for service ID: ${service.id}`);
|
// console.log(`Navigating to service detail for service ID: ${service.id}`);
|
||||||
navigate(`/service/${service.id}`);
|
navigate(`/service/${service.id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ export function useServiceActions(initialServices: Service[]) {
|
|||||||
|
|
||||||
setSelectedService(null);
|
setSelectedService(null);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error deleting service:", error);
|
// console.error("Error deleting service:", error);
|
||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
@@ -134,7 +134,7 @@ export function useServiceActions(initialServices: Service[]) {
|
|||||||
// Toggle the mute alerts status for this specific service
|
// Toggle the mute alerts status for this specific service
|
||||||
const newMuteStatus = !isMuted;
|
const newMuteStatus = !isMuted;
|
||||||
|
|
||||||
console.log(`${newMuteStatus ? "Muting" : "Unmuting"} alerts for service ${service.id} (${service.name})`);
|
// console.log(`${newMuteStatus ? "Muting" : "Unmuting"} alerts for service ${service.id} (${service.name})`);
|
||||||
|
|
||||||
// First update the local state immediately for better UI responsiveness
|
// First update the local state immediately for better UI responsiveness
|
||||||
// Using proper type casting to ensure TypeScript knows we're creating valid Service objects
|
// Using proper type casting to ensure TypeScript knows we're creating valid Service objects
|
||||||
@@ -165,7 +165,7 @@ export function useServiceActions(initialServices: Service[]) {
|
|||||||
await queryClient.invalidateQueries({ queryKey: ["services"] });
|
await queryClient.invalidateQueries({ queryKey: ["services"] });
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating alert settings:", error);
|
// console.error("Error updating alert settings:", error);
|
||||||
|
|
||||||
// Revert the local state change if the server update failed
|
// Revert the local state change if the server update failed
|
||||||
const revertedServices = services.map(s => {
|
const revertedServices = services.map(s => {
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ export function LatestChecksTable({ uptimeData }: { uptimeData: UptimeData[] })
|
|||||||
// Filter incidents by status
|
// Filter incidents by status
|
||||||
const incidents = useMemo(() => {
|
const incidents = useMemo(() => {
|
||||||
const statusChanges = getStatusChangeEvents(uptimeData);
|
const statusChanges = getStatusChangeEvents(uptimeData);
|
||||||
console.log(`Total status changes: ${statusChanges.length}`);
|
// console.log(`Total status changes: ${statusChanges.length}`);
|
||||||
console.log(`Status types in incidents: ${[...new Set(statusChanges.map(i => i.status))].join(', ')}`);
|
// console.log(`Status types in incidents: ${[...new Set(statusChanges.map(i => i.status))].join(', ')}`);
|
||||||
|
|
||||||
if (statusFilter === "all") return statusChanges;
|
if (statusFilter === "all") return statusChanges;
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ export function LatestChecksTable({ uptimeData }: { uptimeData: UptimeData[] })
|
|||||||
// Calculate items per page for pagination display
|
// Calculate items per page for pagination display
|
||||||
const itemsPerPage = pageSize === "all" ? incidents.length : parseInt(pageSize, 10);
|
const itemsPerPage = pageSize === "all" ? incidents.length : parseInt(pageSize, 10);
|
||||||
|
|
||||||
console.log(`Status Filter: ${statusFilter}, Incidents: ${incidents.length}, Includes paused: ${incidents.some(i => i.status === 'paused')}`);
|
// console.log(`Status Filter: ${statusFilter}, Incidents: ${incidents.length}, Includes paused: ${incidents.some(i => i.status === 'paused')}`);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className={`mb-6 transition-colors ${theme === 'dark' ? 'bg-card border-border' : 'bg-white border-gray-200'}`}>
|
<Card className={`mb-6 transition-colors ${theme === 'dark' ? 'bg-card border-border' : 'bg-white border-gray-200'}`}>
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export const getStatusChangeEvents = (uptimeData: UptimeData[]): UptimeData[] =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Found ${statusChanges.length} status changes, including paused status changes: ${statusChanges.some(i => i.status === 'paused')}`);
|
// console.log(`Found ${statusChanges.length} status changes, including paused status changes: ${statusChanges.some(i => i.status === 'paused')}`);
|
||||||
|
|
||||||
return statusChanges;
|
return statusChanges;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ export const TemplateDialog: React.FC<TemplateDialogProps> = ({
|
|||||||
// For debugging purposes
|
// For debugging purposes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
console.log("Template dialog opened. Edit mode:", isEditMode, "Template ID:", templateId);
|
// console.log("Template dialog opened. Edit mode:", isEditMode, "Template ID:", templateId);
|
||||||
|
|
||||||
// Log form values when they change
|
// Log form values when they change
|
||||||
const subscription = form.watch((value) => {
|
const subscription = form.watch((value) => {
|
||||||
console.log("Current form values:", value);
|
// console.log("Current form values:", value);
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => subscription.unsubscribe();
|
return () => subscription.unsubscribe();
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export const AddSSLCertificateForm = ({
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const configs = await alertConfigService.getAlertConfigurations();
|
const configs = await alertConfigService.getAlertConfigurations();
|
||||||
console.log("Fetched notification channels:", configs);
|
// console.log("Fetched notification channels:", configs);
|
||||||
// Only include enabled channels
|
// Only include enabled channels
|
||||||
const enabledConfigs = configs.filter(config => {
|
const enabledConfigs = configs.filter(config => {
|
||||||
// Handle the possibility of enabled being a string
|
// Handle the possibility of enabled being a string
|
||||||
@@ -66,7 +66,7 @@ export const AddSSLCertificateForm = ({
|
|||||||
});
|
});
|
||||||
setAlertConfigs(enabledConfigs);
|
setAlertConfigs(enabledConfigs);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching notification channels:", error);
|
// console.error("Error fetching notification channels:", error);
|
||||||
toast.error(t('failedToLoadCertificates'));
|
toast.error(t('failedToLoadCertificates'));
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -90,7 +90,7 @@ export const AddSSLCertificateForm = ({
|
|||||||
await onSubmit(certData);
|
await onSubmit(certData);
|
||||||
form.reset();
|
form.reset();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error adding SSL certificate:", error);
|
// console.error("Error adding SSL certificate:", error);
|
||||||
toast.error(t('failedToAddCertificate'));
|
toast.error(t('failedToAddCertificate'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const EditSSLCertificateForm = ({ certificate, onSubmit, onCancel, isPend
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const configs = await alertConfigService.getAlertConfigurations();
|
const configs = await alertConfigService.getAlertConfigurations();
|
||||||
console.log("Fetched notification channels:", configs);
|
// console.log("Fetched notification channels:", configs);
|
||||||
// Only include enabled channels
|
// Only include enabled channels
|
||||||
const enabledConfigs = configs.filter(config => {
|
const enabledConfigs = configs.filter(config => {
|
||||||
// Handle the possibility of enabled being a string
|
// Handle the possibility of enabled being a string
|
||||||
@@ -64,7 +64,7 @@ export const EditSSLCertificateForm = ({ certificate, onSubmit, onCancel, isPend
|
|||||||
});
|
});
|
||||||
setAlertConfigs(enabledConfigs);
|
setAlertConfigs(enabledConfigs);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching notification channels:", error);
|
// console.error("Error fetching notification channels:", error);
|
||||||
toast.error(t('failedToLoadCertificates'));
|
toast.error(t('failedToLoadCertificates'));
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ export const SSLDomainContent = () => {
|
|||||||
queryKey: ['ssl-certificates'],
|
queryKey: ['ssl-certificates'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
try {
|
try {
|
||||||
console.log("Fetching SSL certificates from SSLDomainContent...");
|
// console.log("Fetching SSL certificates from SSLDomainContent...");
|
||||||
const result = await fetchSSLCertificates();
|
const result = await fetchSSLCertificates();
|
||||||
console.log("Received SSL certificates:", result);
|
// console.log("Received SSL certificates:", result);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching certificates:", error);
|
// console.error("Error fetching certificates:", error);
|
||||||
toast.error(t('failedToLoadCertificates'));
|
toast.error(t('failedToLoadCertificates'));
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ export const SSLDomainContent = () => {
|
|||||||
toast.success(t('sslCertificateAdded'));
|
toast.success(t('sslCertificateAdded'));
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error("Error adding SSL certificate:", error);
|
// console.error("Error adding SSL certificate:", error);
|
||||||
toast.error(error instanceof Error ? error.message : t('failedToAddCertificate'));
|
toast.error(error instanceof Error ? error.message : t('failedToAddCertificate'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -61,7 +61,7 @@ export const SSLDomainContent = () => {
|
|||||||
// Edit certificate mutation - Updated to ensure thresholds are properly updated
|
// Edit certificate mutation - Updated to ensure thresholds are properly updated
|
||||||
const editMutation = useMutation({
|
const editMutation = useMutation({
|
||||||
mutationFn: async (certificate: SSLCertificate) => {
|
mutationFn: async (certificate: SSLCertificate) => {
|
||||||
console.log("Updating certificate with data:", certificate);
|
// console.log("Updating certificate with data:", certificate);
|
||||||
|
|
||||||
// Create the update data object
|
// Create the update data object
|
||||||
const updateData = {
|
const updateData = {
|
||||||
@@ -70,12 +70,12 @@ export const SSLDomainContent = () => {
|
|||||||
notification_channel: certificate.notification_channel,
|
notification_channel: certificate.notification_channel,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("Update data to be sent:", updateData);
|
// console.log("Update data to be sent:", updateData);
|
||||||
|
|
||||||
// Update certificate in the database using PocketBase directly
|
// Update certificate in the database using PocketBase directly
|
||||||
const updated = await pb.collection('ssl_certificates').update(certificate.id, updateData);
|
const updated = await pb.collection('ssl_certificates').update(certificate.id, updateData);
|
||||||
|
|
||||||
console.log("PocketBase update response:", updated);
|
// console.log("PocketBase update response:", updated);
|
||||||
|
|
||||||
// After updating the settings, refresh the certificate to ensure it's up to date
|
// After updating the settings, refresh the certificate to ensure it's up to date
|
||||||
// This will also check if notification needs to be sent based on updated thresholds
|
// This will also check if notification needs to be sent based on updated thresholds
|
||||||
@@ -90,7 +90,7 @@ export const SSLDomainContent = () => {
|
|||||||
toast.success(t('sslCertificateUpdated'));
|
toast.success(t('sslCertificateUpdated'));
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error("Error updating SSL certificate:", error);
|
// console.error("Error updating SSL certificate:", error);
|
||||||
toast.error(error instanceof Error ? error.message : t('failedToUpdateCertificate'));
|
toast.error(error instanceof Error ? error.message : t('failedToUpdateCertificate'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -103,7 +103,7 @@ export const SSLDomainContent = () => {
|
|||||||
toast.success(t('sslCertificateDeleted'));
|
toast.success(t('sslCertificateDeleted'));
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error("Error deleting SSL certificate:", error);
|
// console.error("Error deleting SSL certificate:", error);
|
||||||
toast.error(error instanceof Error ? error.message : t('failedToDeleteCertificate'));
|
toast.error(error instanceof Error ? error.message : t('failedToDeleteCertificate'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -117,7 +117,7 @@ export const SSLDomainContent = () => {
|
|||||||
toast.success(t('sslCertificateRefreshed').replace('{domain}', data.domain));
|
toast.success(t('sslCertificateRefreshed').replace('{domain}', data.domain));
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error("Error refreshing SSL certificate:", error);
|
// console.error("Error refreshing SSL certificate:", error);
|
||||||
|
|
||||||
let errorMessage = t('failedToCheckCertificate');
|
let errorMessage = t('failedToCheckCertificate');
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ export const SSLDomainContent = () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error("Error refreshing all certificates:", error);
|
// console.error("Error refreshing all certificates:", error);
|
||||||
toast.error(t('failedToCheckCertificate'));
|
toast.error(t('failedToCheckCertificate'));
|
||||||
setIsRefreshingAll(false);
|
setIsRefreshingAll(false);
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ export const SSLDomainContent = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateCertificate = (certificate: SSLCertificate) => {
|
const handleUpdateCertificate = (certificate: SSLCertificate) => {
|
||||||
console.log("Handling certificate update with data:", certificate);
|
// console.log("Handling certificate update with data:", certificate);
|
||||||
editMutation.mutate(certificate);
|
editMutation.mutate(certificate);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export function useSystemSettings() {
|
|||||||
queryKey: ['generalSettings'],
|
queryKey: ['generalSettings'],
|
||||||
queryFn: async (): Promise<GeneralSettings | null> => {
|
queryFn: async (): Promise<GeneralSettings | null> => {
|
||||||
try {
|
try {
|
||||||
console.log('Fetching settings from API...');
|
// console.log('Fetching settings from API...');
|
||||||
const response = await fetch('/api/settings', {
|
const response = await fetch('/api/settings', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -38,14 +38,14 @@ export function useSystemSettings() {
|
|||||||
body: JSON.stringify({ action: 'getSettings' })
|
body: JSON.stringify({ action: 'getSettings' })
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('API response status:', response.status);
|
// console.log('API response status:', response.status);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: ApiResponse = await response.json();
|
const result: ApiResponse = await response.json();
|
||||||
console.log('API response data:', result);
|
// console.log('API response data:', result);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error(result.message || 'Failed to fetch settings');
|
throw new Error(result.message || 'Failed to fetch settings');
|
||||||
@@ -53,7 +53,7 @@ export function useSystemSettings() {
|
|||||||
|
|
||||||
return result.data || null;
|
return result.data || null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching settings:', error);
|
// console.error('Error fetching settings:', error);
|
||||||
toast({
|
toast({
|
||||||
title: t("errorFetchingSettings", "settings"),
|
title: t("errorFetchingSettings", "settings"),
|
||||||
description: error instanceof Error ? error.message : String(error),
|
description: error instanceof Error ? error.message : String(error),
|
||||||
@@ -68,7 +68,7 @@ export function useSystemSettings() {
|
|||||||
// Update settings mutation
|
// Update settings mutation
|
||||||
const updateSettingsMutation = useMutation({
|
const updateSettingsMutation = useMutation({
|
||||||
mutationFn: async (updatedSettings: GeneralSettings): Promise<GeneralSettings> => {
|
mutationFn: async (updatedSettings: GeneralSettings): Promise<GeneralSettings> => {
|
||||||
console.log('Updating settings:', updatedSettings);
|
// console.log('Updating settings:', updatedSettings);
|
||||||
const response = await fetch('/api/settings', {
|
const response = await fetch('/api/settings', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -101,7 +101,7 @@ export function useSystemSettings() {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error('Error updating settings:', error);
|
// console.error('Error updating settings:', error);
|
||||||
toast({
|
toast({
|
||||||
title: t("errorSavingSettings", "settings"),
|
title: t("errorSavingSettings", "settings"),
|
||||||
description: error instanceof Error ? error.message : String(error),
|
description: error instanceof Error ? error.message : String(error),
|
||||||
@@ -113,7 +113,7 @@ export function useSystemSettings() {
|
|||||||
// Test email connection
|
// Test email connection
|
||||||
const testEmailConnectionMutation = useMutation({
|
const testEmailConnectionMutation = useMutation({
|
||||||
mutationFn: async (smtpConfig: any): Promise<{success: boolean, message: string}> => {
|
mutationFn: async (smtpConfig: any): Promise<{success: boolean, message: string}> => {
|
||||||
console.log('Testing email connection:', smtpConfig);
|
// console.log('Testing email connection:', smtpConfig);
|
||||||
const response = await fetch('/api/settings', {
|
const response = await fetch('/api/settings', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -143,7 +143,7 @@ export function useSystemSettings() {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error('Error testing connection:', error);
|
// console.error('Error testing connection:', error);
|
||||||
toast({
|
toast({
|
||||||
title: t("connectionFailed", "settings"),
|
title: t("connectionFailed", "settings"),
|
||||||
description: error instanceof Error ? error.message : String(error),
|
description: error instanceof Error ? error.message : String(error),
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const Dashboard = () => {
|
|||||||
|
|
||||||
// For debugging user data
|
// For debugging user data
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("Current user data:", currentUser);
|
// console.log("Current user data:", currentUser);
|
||||||
}, [currentUser]);
|
}, [currentUser]);
|
||||||
|
|
||||||
// Handle logout
|
// Handle logout
|
||||||
@@ -40,7 +40,7 @@ const Dashboard = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const startActiveServices = async () => {
|
const startActiveServices = async () => {
|
||||||
await serviceService.startAllActiveServices();
|
await serviceService.startAllActiveServices();
|
||||||
console.log("Active services monitoring started");
|
// console.log("Active services monitoring started");
|
||||||
};
|
};
|
||||||
|
|
||||||
startActiveServices();
|
startActiveServices();
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ const SslDomain = () => {
|
|||||||
const { data: certificates = [], isLoading, error, refetch } = useQuery({
|
const { data: certificates = [], isLoading, error, refetch } = useQuery({
|
||||||
queryKey: ['ssl-certificates'],
|
queryKey: ['ssl-certificates'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
console.log("Fetching SSL certificates from SslDomain page...");
|
// console.log("Fetching SSL certificates from SslDomain page...");
|
||||||
try {
|
try {
|
||||||
const result = await fetchSSLCertificates();
|
const result = await fetchSSLCertificates();
|
||||||
console.log("SSL certificates fetch successful, count:", result.length);
|
// console.log("SSL certificates fetch successful, count:", result.length);
|
||||||
return result;
|
return result;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error fetching SSL certificates from page:", err);
|
// console.error("Error fetching SSL certificates from page:", err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -46,7 +46,7 @@ const SslDomain = () => {
|
|||||||
const checkCertificates = async () => {
|
const checkCertificates = async () => {
|
||||||
// Check if we should run daily check
|
// Check if we should run daily check
|
||||||
if (shouldRunDailyCheck()) {
|
if (shouldRunDailyCheck()) {
|
||||||
console.log("Running daily SSL certificate check...");
|
// console.log("Running daily SSL certificate check...");
|
||||||
await checkAllCertificatesAndNotify();
|
await checkAllCertificatesAndNotify();
|
||||||
// Refresh certificate list after daily check
|
// Refresh certificate list after daily check
|
||||||
refetch();
|
refetch();
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ export interface AlertConfiguration {
|
|||||||
|
|
||||||
export const alertConfigService = {
|
export const alertConfigService = {
|
||||||
async getAlertConfigurations(): Promise<AlertConfiguration[]> {
|
async getAlertConfigurations(): Promise<AlertConfiguration[]> {
|
||||||
console.info("Fetching alert configurations");
|
// console.info("Fetching alert configurations");
|
||||||
try {
|
try {
|
||||||
const response = await pb.collection('alert_configurations').getList(1, 50);
|
const response = await pb.collection('alert_configurations').getList(1, 50);
|
||||||
console.info("Alert configurations response:", response);
|
// console.info("Alert configurations response:", response);
|
||||||
return response.items as AlertConfiguration[];
|
return response.items as AlertConfiguration[];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching alert configurations:", error);
|
// console.error("Error fetching alert configurations:", error);
|
||||||
toast({
|
toast({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Failed to load notification settings",
|
description: "Failed to load notification settings",
|
||||||
@@ -39,17 +39,17 @@ export const alertConfigService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async createAlertConfiguration(config: Omit<AlertConfiguration, 'id' | 'collectionId' | 'collectionName' | 'created' | 'updated'>): Promise<AlertConfiguration | null> {
|
async createAlertConfiguration(config: Omit<AlertConfiguration, 'id' | 'collectionId' | 'collectionName' | 'created' | 'updated'>): Promise<AlertConfiguration | null> {
|
||||||
console.info("Creating alert configuration:", config);
|
// console.info("Creating alert configuration:", config);
|
||||||
try {
|
try {
|
||||||
const result = await pb.collection('alert_configurations').create(config);
|
const result = await pb.collection('alert_configurations').create(config);
|
||||||
console.info("Alert configuration created:", result);
|
// console.info("Alert configuration created:", result);
|
||||||
toast({
|
toast({
|
||||||
title: "Success",
|
title: "Success",
|
||||||
description: "Notification settings saved successfully",
|
description: "Notification settings saved successfully",
|
||||||
});
|
});
|
||||||
return result as AlertConfiguration;
|
return result as AlertConfiguration;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error creating alert configuration:", error);
|
// console.error("Error creating alert configuration:", error);
|
||||||
toast({
|
toast({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Failed to save notification settings",
|
description: "Failed to save notification settings",
|
||||||
@@ -60,17 +60,17 @@ export const alertConfigService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async updateAlertConfiguration(id: string, config: Partial<AlertConfiguration>): Promise<AlertConfiguration | null> {
|
async updateAlertConfiguration(id: string, config: Partial<AlertConfiguration>): Promise<AlertConfiguration | null> {
|
||||||
console.info(`Updating alert configuration ${id}:`, config);
|
// console.info(`Updating alert configuration ${id}:`, config);
|
||||||
try {
|
try {
|
||||||
const result = await pb.collection('alert_configurations').update(id, config);
|
const result = await pb.collection('alert_configurations').update(id, config);
|
||||||
console.info("Alert configuration updated:", result);
|
// console.info("Alert configuration updated:", result);
|
||||||
toast({
|
toast({
|
||||||
title: "Success",
|
title: "Success",
|
||||||
description: "Notification settings updated successfully",
|
description: "Notification settings updated successfully",
|
||||||
});
|
});
|
||||||
return result as AlertConfiguration;
|
return result as AlertConfiguration;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating alert configuration:", error);
|
// console.error("Error updating alert configuration:", error);
|
||||||
toast({
|
toast({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Failed to update notification settings",
|
description: "Failed to update notification settings",
|
||||||
@@ -81,17 +81,17 @@ export const alertConfigService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async deleteAlertConfiguration(id: string): Promise<boolean> {
|
async deleteAlertConfiguration(id: string): Promise<boolean> {
|
||||||
console.info(`Deleting alert configuration ${id}`);
|
// console.info(`Deleting alert configuration ${id}`);
|
||||||
try {
|
try {
|
||||||
await pb.collection('alert_configurations').delete(id);
|
await pb.collection('alert_configurations').delete(id);
|
||||||
console.info("Alert configuration deleted");
|
// console.info("Alert configuration deleted");
|
||||||
toast({
|
toast({
|
||||||
title: "Success",
|
title: "Success",
|
||||||
description: "Notification channel removed",
|
description: "Notification channel removed",
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error deleting alert configuration:", error);
|
// console.error("Error deleting alert configuration:", error);
|
||||||
toast({
|
toast({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Failed to remove notification channel",
|
description: "Failed to remove notification channel",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const authService = {
|
|||||||
try {
|
try {
|
||||||
// First try to login as a regular admin user
|
// First try to login as a regular admin user
|
||||||
try {
|
try {
|
||||||
console.log("Attempting to login as admin user");
|
// console.log("Attempting to login as admin user");
|
||||||
const authData = await pb.collection('users').authWithPassword(email, password);
|
const authData = await pb.collection('users').authWithPassword(email, password);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -30,7 +30,7 @@ export const authService = {
|
|||||||
role: authData.record.role || "admin"
|
role: authData.record.role || "admin"
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to login as admin, trying as superadmin", error);
|
// console.log("Failed to login as admin, trying as superadmin", error);
|
||||||
|
|
||||||
// If regular user login fails, try superadmin
|
// If regular user login fails, try superadmin
|
||||||
const authData = await pb.collection('_superusers').authWithPassword(email, password);
|
const authData = await pb.collection('_superusers').authWithPassword(email, password);
|
||||||
@@ -44,7 +44,7 @@ export const authService = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Login failed:', error);
|
// console.error('Login failed:', error);
|
||||||
throw new Error('Authentication failed. Please check your credentials.');
|
throw new Error('Authentication failed. Please check your credentials.');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -63,7 +63,7 @@ export const authService = {
|
|||||||
if (!userData) return null;
|
if (!userData) return null;
|
||||||
|
|
||||||
// Log the full user data for debugging
|
// Log the full user data for debugging
|
||||||
console.log("Raw user data from authStore:", userData);
|
//console.log("Raw user data from authStore:", userData);
|
||||||
|
|
||||||
// Determine if this is a superadmin by checking the collection name
|
// Determine if this is a superadmin by checking the collection name
|
||||||
const isSuperAdmin = userData.collectionName === '_superusers';
|
const isSuperAdmin = userData.collectionName === '_superusers';
|
||||||
@@ -90,13 +90,13 @@ export const authService = {
|
|||||||
try {
|
try {
|
||||||
// Fetch the latest user data from the server
|
// Fetch the latest user data from the server
|
||||||
const userId = (pb.authStore.model as any).id;
|
const userId = (pb.authStore.model as any).id;
|
||||||
console.log("Refreshing user data for ID:", userId);
|
// console.log("Refreshing user data for ID:", userId);
|
||||||
|
|
||||||
// Use the getOne method directly to refresh the auth store
|
// Use the getOne method directly to refresh the auth store
|
||||||
await pb.collection('users').getOne(userId);
|
await pb.collection('users').getOne(userId);
|
||||||
console.log("User data refreshed successfully");
|
// console.log("User data refreshed successfully");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to refresh user data:', error);
|
// console.error('Failed to refresh user data:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -3,12 +3,12 @@ import { IncidentItem } from './types';
|
|||||||
|
|
||||||
// Export functions to update and invalidate the cache
|
// Export functions to update and invalidate the cache
|
||||||
export const updateCache = (data: IncidentItem[]) => {
|
export const updateCache = (data: IncidentItem[]) => {
|
||||||
console.log(`Updating cache with ${data.length} incidents`);
|
// console.log(`Updating cache with ${data.length} incidents`);
|
||||||
// The actual cache is now maintained in incidentFetch.ts
|
// The actual cache is now maintained in incidentFetch.ts
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reset cache and request state
|
// Reset cache and request state
|
||||||
export const invalidateCache = () => {
|
export const invalidateCache = () => {
|
||||||
console.log('Invalidating incidents cache');
|
// console.log('Invalidating incidents cache');
|
||||||
// The invalidation is handled in incidentFetch.ts implementation
|
// The invalidation is handled in incidentFetch.ts implementation
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const isCacheValid = (): boolean => {
|
|||||||
export const getAllIncidents = async (forceRefresh = false): Promise<IncidentItem[]> => {
|
export const getAllIncidents = async (forceRefresh = false): Promise<IncidentItem[]> => {
|
||||||
// If a request is in progress, wait for it to complete rather than making a new one
|
// If a request is in progress, wait for it to complete rather than making a new one
|
||||||
if (isRequestInProgress) {
|
if (isRequestInProgress) {
|
||||||
console.log('Request already in progress, waiting for completion');
|
// console.log('Request already in progress, waiting for completion');
|
||||||
try {
|
try {
|
||||||
if (pendingRequest) {
|
if (pendingRequest) {
|
||||||
await pendingRequest;
|
await pendingRequest;
|
||||||
@@ -39,12 +39,12 @@ export const getAllIncidents = async (forceRefresh = false): Promise<IncidentIte
|
|||||||
|
|
||||||
// Use cache if available, not expired, and not forced refresh
|
// Use cache if available, not expired, and not forced refresh
|
||||||
if (!forceRefresh && isCacheValid()) {
|
if (!forceRefresh && isCacheValid()) {
|
||||||
console.log('Using cached incidents data from', new Date(incidentsCache!.timestamp).toLocaleTimeString());
|
// console.log('Using cached incidents data from', new Date(incidentsCache!.timestamp).toLocaleTimeString());
|
||||||
return incidentsCache!.data;
|
return incidentsCache!.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('Fetching all incidents from API...');
|
// console.log('Fetching all incidents from API...');
|
||||||
isRequestInProgress = true;
|
isRequestInProgress = true;
|
||||||
|
|
||||||
// Implement timeout for the request
|
// Implement timeout for the request
|
||||||
@@ -72,7 +72,7 @@ export const getAllIncidents = async (forceRefresh = false): Promise<IncidentIte
|
|||||||
isRequestInProgress = false;
|
isRequestInProgress = false;
|
||||||
|
|
||||||
if (!result || !result.items) {
|
if (!result || !result.items) {
|
||||||
console.warn('No incidents found in API response');
|
// console.warn('No incidents found in API response');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ export const getAllIncidents = async (forceRefresh = false): Promise<IncidentIte
|
|||||||
// Update cache
|
// Update cache
|
||||||
updateCache(normalizedItems);
|
updateCache(normalizedItems);
|
||||||
|
|
||||||
console.log(`Fetched ${normalizedItems.length} incidents at ${new Date().toLocaleTimeString()}`);
|
// console.log(`Fetched ${normalizedItems.length} incidents at ${new Date().toLocaleTimeString()}`);
|
||||||
return normalizedItems;
|
return normalizedItems;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if ((error as any)?.isAbort) {
|
if ((error as any)?.isAbort) {
|
||||||
@@ -89,7 +89,7 @@ export const getAllIncidents = async (forceRefresh = false): Promise<IncidentIte
|
|||||||
return incidentsCache?.data || [];
|
return incidentsCache?.data || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error('Error fetching incidents:', error);
|
// console.error('Error fetching incidents:', error);
|
||||||
|
|
||||||
// Clear states to allow retry
|
// Clear states to allow retry
|
||||||
pendingRequest = null;
|
pendingRequest = null;
|
||||||
@@ -102,7 +102,7 @@ export const getAllIncidents = async (forceRefresh = false): Promise<IncidentIte
|
|||||||
|
|
||||||
// Still return cached data even on error
|
// Still return cached data even on error
|
||||||
if (incidentsCache) {
|
if (incidentsCache) {
|
||||||
console.log('Returning stale cached data after error');
|
// console.log('Returning stale cached data after error');
|
||||||
return incidentsCache.data;
|
return incidentsCache.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,13 +113,13 @@ export const getAllIncidents = async (forceRefresh = false): Promise<IncidentIte
|
|||||||
// Get incident by id
|
// Get incident by id
|
||||||
export const getIncidentById = async (id: string): Promise<IncidentItem | null> => {
|
export const getIncidentById = async (id: string): Promise<IncidentItem | null> => {
|
||||||
try {
|
try {
|
||||||
console.log(`Fetching incident with ID: ${id}`);
|
// console.log(`Fetching incident with ID: ${id}`);
|
||||||
|
|
||||||
// First check if the incident exists in the cache
|
// First check if the incident exists in the cache
|
||||||
if (isCacheValid() && incidentsCache) {
|
if (isCacheValid() && incidentsCache) {
|
||||||
const cachedIncident = incidentsCache.data.find(incident => incident.id === id);
|
const cachedIncident = incidentsCache.data.find(incident => incident.id === id);
|
||||||
if (cachedIncident) {
|
if (cachedIncident) {
|
||||||
console.log('Incident found in cache');
|
// console.log('Incident found in cache');
|
||||||
return cachedIncident;
|
return cachedIncident;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ export const getIncidentById = async (id: string): Promise<IncidentItem | null>
|
|||||||
return normalizedIncident;
|
return normalizedIncident;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error fetching incident with ID ${id}:`, error);
|
// console.error(`Error fetching incident with ID ${id}:`, error);
|
||||||
|
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
throw new Error(`Failed to fetch incident: ${error.message}`);
|
throw new Error(`Failed to fetch incident: ${error.message}`);
|
||||||
|
|||||||
@@ -16,20 +16,20 @@ export const maintenanceNotificationService = {
|
|||||||
*/
|
*/
|
||||||
async sendMaintenanceNotification({ maintenance, notificationType }: NotificationParams): Promise<boolean> {
|
async sendMaintenanceNotification({ maintenance, notificationType }: NotificationParams): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
console.log(`Preparing to send ${notificationType} notification for maintenance: ${maintenance.title}`);
|
// console.log(`Preparing to send ${notificationType} notification for maintenance: ${maintenance.title}`);
|
||||||
|
|
||||||
// Get notification channel ID - try both fields
|
// Get notification channel ID - try both fields
|
||||||
let notificationChannelId = maintenance.notification_channel_id;
|
let notificationChannelId = maintenance.notification_channel_id;
|
||||||
|
|
||||||
// If notification_channel_id is empty, try to use notification_id
|
// If notification_channel_id is empty, try to use notification_id
|
||||||
if (!notificationChannelId && maintenance.notification_id) {
|
if (!notificationChannelId && maintenance.notification_id) {
|
||||||
console.log(`No notification_channel_id found, using notification_id: ${maintenance.notification_id}`);
|
// console.log(`No notification_channel_id found, using notification_id: ${maintenance.notification_id}`);
|
||||||
notificationChannelId = maintenance.notification_id;
|
notificationChannelId = maintenance.notification_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if maintenance has notification channel configured
|
// Check if maintenance has notification channel configured
|
||||||
if (!notificationChannelId) {
|
if (!notificationChannelId) {
|
||||||
console.log("No notification channel configured for this maintenance");
|
// console.log("No notification channel configured for this maintenance");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,19 +41,19 @@ export const maintenanceNotificationService = {
|
|||||||
const config = await pb.collection('alert_configurations').getOne(notificationChannelId);
|
const config = await pb.collection('alert_configurations').getOne(notificationChannelId);
|
||||||
notificationConfig = config as unknown as AlertConfiguration;
|
notificationConfig = config as unknown as AlertConfiguration;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch notification configuration:", error);
|
// console.error("Failed to fetch notification configuration:", error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!notificationConfig.enabled) {
|
if (!notificationConfig.enabled) {
|
||||||
console.log("Notification channel is disabled");
|
// console.log("Notification channel is disabled");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create notification message based on type
|
// Create notification message based on type
|
||||||
const message = this.generateMaintenanceMessage(maintenance, notificationType);
|
const message = this.generateMaintenanceMessage(maintenance, notificationType);
|
||||||
|
|
||||||
console.log(`Sending ${notificationConfig.notification_type} notification with message: ${message}`);
|
// console.log(`Sending ${notificationConfig.notification_type} notification with message: ${message}`);
|
||||||
|
|
||||||
// Send notification based on channel type
|
// Send notification based on channel type
|
||||||
if (notificationConfig.notification_type === 'telegram') {
|
if (notificationConfig.notification_type === 'telegram') {
|
||||||
@@ -62,10 +62,10 @@ export const maintenanceNotificationService = {
|
|||||||
|
|
||||||
// Add more notification types here as needed
|
// Add more notification types here as needed
|
||||||
|
|
||||||
console.log(`Unsupported notification type: ${notificationConfig.notification_type}`);
|
// console.log(`Unsupported notification type: ${notificationConfig.notification_type}`);
|
||||||
return false;
|
return false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error sending maintenance notification:", error);
|
// console.error("Error sending maintenance notification:", error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -115,12 +115,12 @@ export const maintenanceNotificationService = {
|
|||||||
|
|
||||||
// Set up scheduled maintenance notifications
|
// Set up scheduled maintenance notifications
|
||||||
export const setupMaintenanceNotificationsScheduler = () => {
|
export const setupMaintenanceNotificationsScheduler = () => {
|
||||||
console.log("Setting up maintenance notifications scheduler");
|
// console.log("Setting up maintenance notifications scheduler");
|
||||||
|
|
||||||
// Check every minute for maintenance that needs notifications
|
// Check every minute for maintenance that needs notifications
|
||||||
const checkInterval = setInterval(async () => {
|
const checkInterval = setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
console.log("Checking for maintenance notifications to send...");
|
// console.log("Checking for maintenance notifications to send...");
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
// Fetch upcoming and ongoing maintenance
|
// Fetch upcoming and ongoing maintenance
|
||||||
@@ -143,7 +143,7 @@ export const setupMaintenanceNotificationsScheduler = () => {
|
|||||||
startTime <= new Date(now.getTime() + 60000) &&
|
startTime <= new Date(now.getTime() + 60000) &&
|
||||||
startTime > new Date(now.getTime() - 60000)) {
|
startTime > new Date(now.getTime() - 60000)) {
|
||||||
|
|
||||||
console.log(`Maintenance ${maintenance.title} is starting now, sending notification`);
|
// console.log(`Maintenance ${maintenance.title} is starting now, sending notification`);
|
||||||
await maintenanceNotificationService.sendMaintenanceNotification({
|
await maintenanceNotificationService.sendMaintenanceNotification({
|
||||||
maintenance,
|
maintenance,
|
||||||
notificationType: 'start'
|
notificationType: 'start'
|
||||||
@@ -160,7 +160,7 @@ export const setupMaintenanceNotificationsScheduler = () => {
|
|||||||
endTime <= new Date(now.getTime() + 60000) &&
|
endTime <= new Date(now.getTime() + 60000) &&
|
||||||
endTime > new Date(now.getTime() - 60000)) {
|
endTime > new Date(now.getTime() - 60000)) {
|
||||||
|
|
||||||
console.log(`Maintenance ${maintenance.title} is ending now, sending notification`);
|
// console.log(`Maintenance ${maintenance.title} is ending now, sending notification`);
|
||||||
await maintenanceNotificationService.sendMaintenanceNotification({
|
await maintenanceNotificationService.sendMaintenanceNotification({
|
||||||
maintenance,
|
maintenance,
|
||||||
notificationType: 'end'
|
notificationType: 'end'
|
||||||
@@ -173,7 +173,7 @@ export const setupMaintenanceNotificationsScheduler = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error checking maintenance notifications:", error);
|
// console.error("Error checking maintenance notifications:", error);
|
||||||
}
|
}
|
||||||
}, 60000); // Check every minute
|
}, 60000); // Check every minute
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ let notificationScheduler: NodeJS.Timeout | null = null;
|
|||||||
export const initMaintenanceNotifications = () => {
|
export const initMaintenanceNotifications = () => {
|
||||||
if (notificationScheduler === null) {
|
if (notificationScheduler === null) {
|
||||||
notificationScheduler = setupMaintenanceNotificationsScheduler();
|
notificationScheduler = setupMaintenanceNotificationsScheduler();
|
||||||
console.log("Maintenance notifications scheduler initialized");
|
// console.log("Maintenance notifications scheduler initialized");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -194,6 +194,6 @@ export const stopMaintenanceNotifications = () => {
|
|||||||
if (notificationScheduler !== null) {
|
if (notificationScheduler !== null) {
|
||||||
clearInterval(notificationScheduler);
|
clearInterval(notificationScheduler);
|
||||||
notificationScheduler = null;
|
notificationScheduler = null;
|
||||||
console.log("Maintenance notifications scheduler stopped");
|
// console.log("Maintenance notifications scheduler stopped");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ export async function startAllActiveServices(): Promise<void> {
|
|||||||
filter: 'status != "paused"'
|
filter: 'status != "paused"'
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Starting monitoring for ${result.items.length} active services`);
|
// console.log(`Starting monitoring for ${result.items.length} active services`);
|
||||||
|
|
||||||
// Start monitoring each active service
|
// Start monitoring each active service
|
||||||
for (const service of result.items) {
|
for (const service of result.items) {
|
||||||
await startMonitoringService(service.id);
|
await startMonitoringService(service.id);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error starting all active services:", error);
|
// console.error("Error starting all active services:", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export async function startMonitoringService(serviceId: string): Promise<void> {
|
|||||||
try {
|
try {
|
||||||
// First check if the service is already being monitored
|
// First check if the service is already being monitored
|
||||||
if (monitoringIntervals.has(serviceId)) {
|
if (monitoringIntervals.has(serviceId)) {
|
||||||
console.log(`Service ${serviceId} is already being monitored`);
|
// console.log(`Service ${serviceId} is already being monitored`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,11 +18,11 @@ export async function startMonitoringService(serviceId: string): Promise<void> {
|
|||||||
|
|
||||||
// If service was manually paused, don't auto-resume
|
// If service was manually paused, don't auto-resume
|
||||||
if (service.status === "paused") {
|
if (service.status === "paused") {
|
||||||
console.log(`Service ${serviceId} (${service.name}) is paused. Not starting monitoring.`);
|
// console.log(`Service ${serviceId} (${service.name}) is paused. Not starting monitoring.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Starting monitoring for service ${serviceId} (${service.name})`);
|
// console.log(`Starting monitoring for service ${serviceId} (${service.name})`);
|
||||||
|
|
||||||
// Update the service status to active/up in the database
|
// Update the service status to active/up in the database
|
||||||
await pb.collection('services').update(serviceId, {
|
await pb.collection('services').update(serviceId, {
|
||||||
@@ -32,18 +32,18 @@ export async function startMonitoringService(serviceId: string): Promise<void> {
|
|||||||
// The actual service checking is now handled by the Go microservice
|
// The actual service checking is now handled by the Go microservice
|
||||||
// This frontend service just tracks the monitoring state
|
// This frontend service just tracks the monitoring state
|
||||||
const intervalMs = (service.heartbeat_interval || 60) * 1000;
|
const intervalMs = (service.heartbeat_interval || 60) * 1000;
|
||||||
console.log(`Service ${service.name} monitoring delegated to backend service`);
|
// console.log(`Service ${service.name} monitoring delegated to backend service`);
|
||||||
|
|
||||||
// Store a placeholder interval to track that this service is being monitored
|
// Store a placeholder interval to track that this service is being monitored
|
||||||
const intervalId = window.setInterval(() => {
|
const intervalId = window.setInterval(() => {
|
||||||
console.log(`Monitoring active for service ${service.name} (handled by backend)`);
|
// console.log(`Monitoring active for service ${service.name} (handled by backend)`);
|
||||||
}, intervalMs);
|
}, intervalMs);
|
||||||
|
|
||||||
// Store the interval ID for this service
|
// Store the interval ID for this service
|
||||||
monitoringIntervals.set(serviceId, intervalId);
|
monitoringIntervals.set(serviceId, intervalId);
|
||||||
|
|
||||||
console.log(`Monitoring registered for service ${serviceId}`);
|
// console.log(`Monitoring registered for service ${serviceId}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error starting service monitoring:", error);
|
// console.error("Error starting service monitoring:", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ export const serviceService = {
|
|||||||
regional_monitoring_enabled: item.regional_status === "enabled", // Backward compatibility
|
regional_monitoring_enabled: item.regional_status === "enabled", // Backward compatibility
|
||||||
}));
|
}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching services:", error);
|
// console.error("Error fetching services:", error);
|
||||||
throw new Error('Failed to load services data.');
|
throw new Error('Failed to load services data.');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { toast } from "sonner";
|
|||||||
*/
|
*/
|
||||||
export const fetchSSLCertificates = async (): Promise<SSLCertificate[]> => {
|
export const fetchSSLCertificates = async (): Promise<SSLCertificate[]> => {
|
||||||
try {
|
try {
|
||||||
console.log("Fetching SSL certificates from PocketBase...");
|
// console.log("Fetching SSL certificates from PocketBase...");
|
||||||
|
|
||||||
// Using the direct API path to fetch SSL certificates
|
// Using the direct API path to fetch SSL certificates
|
||||||
const endpoint = "/api/collections/ssl_certificates/records";
|
const endpoint = "/api/collections/ssl_certificates/records";
|
||||||
@@ -23,7 +23,7 @@ export const fetchSSLCertificates = async (): Promise<SSLCertificate[]> => {
|
|||||||
const queryString = new URLSearchParams(params as any).toString();
|
const queryString = new URLSearchParams(params as any).toString();
|
||||||
const fullEndpoint = `${endpoint}?${queryString}`;
|
const fullEndpoint = `${endpoint}?${queryString}`;
|
||||||
|
|
||||||
console.log("Fetching SSL certificates from:", fullEndpoint);
|
// console.log("Fetching SSL certificates from:", fullEndpoint);
|
||||||
const response = await pb.send(fullEndpoint, {
|
const response = await pb.send(fullEndpoint, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
@@ -39,14 +39,14 @@ export const fetchSSLCertificates = async (): Promise<SSLCertificate[]> => {
|
|||||||
throw new Error("Invalid response format from PocketBase API");
|
throw new Error("Invalid response format from PocketBase API");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Received SSL certificates:", response.items.length);
|
// console.log("Received SSL certificates:", response.items.length);
|
||||||
|
|
||||||
// Map items to SSLCertificate[] type with validation
|
// Map items to SSLCertificate[] type with validation
|
||||||
return response.items.map(item => {
|
return response.items.map(item => {
|
||||||
const cert = item as SSLCertificate;
|
const cert = item as SSLCertificate;
|
||||||
|
|
||||||
// Log certificate details for debugging
|
// Log certificate details for debugging
|
||||||
console.log(`Certificate for ${cert.domain}: Issued by ${cert.issuer_o}, Days left: ${cert.days_left}`);
|
// console.log(`Certificate for ${cert.domain}: Issued by ${cert.issuer_o}, Days left: ${cert.days_left}`);
|
||||||
|
|
||||||
// Ensure dates are valid
|
// Ensure dates are valid
|
||||||
try {
|
try {
|
||||||
@@ -54,7 +54,7 @@ export const fetchSSLCertificates = async (): Promise<SSLCertificate[]> => {
|
|||||||
if (cert.valid_till) new Date(cert.valid_till).toISOString();
|
if (cert.valid_till) new Date(cert.valid_till).toISOString();
|
||||||
if (cert.last_notified) new Date(cert.last_notified).toISOString();
|
if (cert.last_notified) new Date(cert.last_notified).toISOString();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("Invalid date found in certificate", cert.id, e);
|
// console.warn("Invalid date found in certificate", cert.id, e);
|
||||||
// Fix invalid dates if needed
|
// Fix invalid dates if needed
|
||||||
if (cert.valid_from && isNaN(new Date(cert.valid_from).getTime())) {
|
if (cert.valid_from && isNaN(new Date(cert.valid_from).getTime())) {
|
||||||
cert.valid_from = new Date().toISOString();
|
cert.valid_from = new Date().toISOString();
|
||||||
@@ -74,7 +74,7 @@ export const fetchSSLCertificates = async (): Promise<SSLCertificate[]> => {
|
|||||||
const diffTime = expirationDate.getTime() - currentDate.getTime();
|
const diffTime = expirationDate.getTime() - currentDate.getTime();
|
||||||
cert.days_left = Math.ceil(diffTime / (1000 * 3600 * 24));
|
cert.days_left = Math.ceil(diffTime / (1000 * 3600 * 24));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("Error calculating days_left for certificate", cert.id, e);
|
// console.warn("Error calculating days_left for certificate", cert.id, e);
|
||||||
cert.days_left = 0;
|
cert.days_left = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ export const fetchSSLCertificates = async (): Promise<SSLCertificate[]> => {
|
|||||||
return cert;
|
return cert;
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching SSL certificates:", error);
|
// console.error("Error fetching SSL certificates:", error);
|
||||||
toast.error("Failed to fetch SSL certificates. Please try again later.");
|
toast.error("Failed to fetch SSL certificates. Please try again later.");
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const getCollectionForServiceType = (serviceType: string): string => {
|
|||||||
export const uptimeService = {
|
export const uptimeService = {
|
||||||
async recordUptimeData(data: UptimeData): Promise<void> {
|
async recordUptimeData(data: UptimeData): Promise<void> {
|
||||||
try {
|
try {
|
||||||
console.log(`Recording uptime data for service ${data.serviceId || data.service_id}: Status ${data.status}, Response time: ${data.responseTime}ms`);
|
// console.log(`Recording uptime data for service ${data.serviceId || data.service_id}: Status ${data.status}, Response time: ${data.responseTime}ms`);
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
$autoCancel: false,
|
$autoCancel: false,
|
||||||
@@ -50,9 +50,9 @@ export const uptimeService = {
|
|||||||
const keysToDelete = Array.from(uptimeCache.keys()).filter(key => key.includes(`uptime_${serviceId}`));
|
const keysToDelete = Array.from(uptimeCache.keys()).filter(key => key.includes(`uptime_${serviceId}`));
|
||||||
keysToDelete.forEach(key => uptimeCache.delete(key));
|
keysToDelete.forEach(key => uptimeCache.delete(key));
|
||||||
|
|
||||||
console.log(`Uptime data recorded successfully with ID: ${record.id}`);
|
// console.log(`Uptime data recorded successfully with ID: ${record.id}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error recording uptime data:", error);
|
// console.error("Error recording uptime data:", error);
|
||||||
throw new Error(`Failed to record uptime data: ${error}`);
|
throw new Error(`Failed to record uptime data: ${error}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -66,7 +66,7 @@ export const uptimeService = {
|
|||||||
): Promise<UptimeData[]> {
|
): Promise<UptimeData[]> {
|
||||||
try {
|
try {
|
||||||
if (!serviceId) {
|
if (!serviceId) {
|
||||||
console.log('No serviceId provided to getUptimeHistory');
|
// console.log('No serviceId provided to getUptimeHistory');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,13 +75,13 @@ export const uptimeService = {
|
|||||||
// Check cache
|
// Check cache
|
||||||
const cached = uptimeCache.get(cacheKey);
|
const cached = uptimeCache.get(cacheKey);
|
||||||
if (cached && (Date.now() - cached.timestamp) < cached.expiresIn) {
|
if (cached && (Date.now() - cached.timestamp) < cached.expiresIn) {
|
||||||
console.log(`Using cached uptime history for service ${serviceId}`);
|
// console.log(`Using cached uptime history for service ${serviceId}`);
|
||||||
return cached.data;
|
return cached.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the correct collection based on service type
|
// Determine the correct collection based on service type
|
||||||
const collection = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data';
|
const collection = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data';
|
||||||
console.log(`Fetching default uptime history for service ${serviceId} from collection ${collection}, limit: ${limit}`);
|
// console.log(`Fetching default uptime history for service ${serviceId} from collection ${collection}, limit: ${limit}`);
|
||||||
|
|
||||||
// Build filter to get records for specific service_id
|
// Build filter to get records for specific service_id
|
||||||
let filter = `service_id='${serviceId}'`;
|
let filter = `service_id='${serviceId}'`;
|
||||||
@@ -91,7 +91,7 @@ export const uptimeService = {
|
|||||||
const startUTC = startDate.toISOString();
|
const startUTC = startDate.toISOString();
|
||||||
const endUTC = endDate.toISOString();
|
const endUTC = endDate.toISOString();
|
||||||
|
|
||||||
console.log(`Date filter: ${startUTC} to ${endUTC}`);
|
// console.log(`Date filter: ${startUTC} to ${endUTC}`);
|
||||||
filter += ` && timestamp >= "${startUTC}" && timestamp <= "${endUTC}"`;
|
filter += ` && timestamp >= "${startUTC}" && timestamp <= "${endUTC}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,16 +102,16 @@ export const uptimeService = {
|
|||||||
$cancelKey: `uptime_history_${serviceId}_${Date.now()}`
|
$cancelKey: `uptime_history_${serviceId}_${Date.now()}`
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(`Filter query for default data: ${filter} on collection: ${collection}`);
|
// console.log(`Filter query for default data: ${filter} on collection: ${collection}`);
|
||||||
|
|
||||||
const response = await pb.collection(collection).getList(1, limit, options);
|
const response = await pb.collection(collection).getList(1, limit, options);
|
||||||
|
|
||||||
console.log(`Fetched ${response.items.length} records for service ${serviceId} from ${collection}`);
|
// console.log(`Fetched ${response.items.length} records for service ${serviceId} from ${collection}`);
|
||||||
|
|
||||||
if (response.items.length > 0) {
|
if (response.items.length > 0) {
|
||||||
console.log(`Date range in results: ${response.items[response.items.length - 1].timestamp} to ${response.items[0].timestamp}`);
|
// console.log(`Date range in results: ${response.items[response.items.length - 1].timestamp} to ${response.items[0].timestamp}`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`No records found for service_id '${serviceId}' in collection: ${collection}`);
|
// console.log(`No records found for service_id '${serviceId}' in collection: ${collection}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform the response items to UptimeData format
|
// Transform the response items to UptimeData format
|
||||||
@@ -137,18 +137,18 @@ export const uptimeService = {
|
|||||||
|
|
||||||
return uptimeData;
|
return uptimeData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error fetching uptime history for service ${serviceId}:`, error);
|
// console.error(`Error fetching uptime history for service ${serviceId}:`, error);
|
||||||
|
|
||||||
// Try to return cached data as fallback
|
// Try to return cached data as fallback
|
||||||
const cacheKey = `uptime_${serviceId}_${limit}_${startDate?.toISOString() || ''}_${endDate?.toISOString() || ''}_${serviceType || 'default'}_default`;
|
const cacheKey = `uptime_${serviceId}_${limit}_${startDate?.toISOString() || ''}_${endDate?.toISOString() || ''}_${serviceType || 'default'}_default`;
|
||||||
const cached = uptimeCache.get(cacheKey);
|
const cached = uptimeCache.get(cacheKey);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
console.log(`Using expired cached data for service ${serviceId} due to fetch error`);
|
// console.log(`Using expired cached data for service ${serviceId} due to fetch error`);
|
||||||
return cached.data;
|
return cached.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return empty array instead of throwing to prevent UI crashes
|
// Return empty array instead of throwing to prevent UI crashes
|
||||||
console.log(`Returning empty array for service ${serviceId} due to fetch error`);
|
// console.log(`Returning empty array for service ${serviceId} due to fetch error`);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -164,7 +164,7 @@ export const uptimeService = {
|
|||||||
): Promise<UptimeData[]> {
|
): Promise<UptimeData[]> {
|
||||||
try {
|
try {
|
||||||
if (!regionName || !agentId) {
|
if (!regionName || !agentId) {
|
||||||
console.log('No region name or agent ID provided for regional query');
|
// console.log('No region name or agent ID provided for regional query');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,13 +173,13 @@ export const uptimeService = {
|
|||||||
// Check cache
|
// Check cache
|
||||||
const cached = uptimeCache.get(cacheKey);
|
const cached = uptimeCache.get(cacheKey);
|
||||||
if (cached && (Date.now() - cached.timestamp) < cached.expiresIn) {
|
if (cached && (Date.now() - cached.timestamp) < cached.expiresIn) {
|
||||||
console.log(`Using cached regional uptime history for service ${serviceId}`);
|
// console.log(`Using cached regional uptime history for service ${serviceId}`);
|
||||||
return cached.data;
|
return cached.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the correct collection based on service type
|
// Determine the correct collection based on service type
|
||||||
const collection = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data';
|
const collection = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data';
|
||||||
console.log(`Fetching regional uptime history from collection: ${collection} for service: ${serviceId}, region: ${regionName}, agent: ${agentId}`);
|
// console.log(`Fetching regional uptime history from collection: ${collection} for service: ${serviceId}, region: ${regionName}, agent: ${agentId}`);
|
||||||
|
|
||||||
// Build filter for regional agent data
|
// Build filter for regional agent data
|
||||||
let filter = `service_id="${serviceId}" && region_name="${regionName}" && agent_id="${agentId}"`;
|
let filter = `service_id="${serviceId}" && region_name="${regionName}" && agent_id="${agentId}"`;
|
||||||
@@ -190,7 +190,7 @@ export const uptimeService = {
|
|||||||
filter += ` && timestamp>="${startISO}" && timestamp<="${endISO}"`;
|
filter += ` && timestamp>="${startISO}" && timestamp<="${endISO}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Regional filter query: ${filter} on collection: ${collection}`);
|
// console.log(`Regional filter query: ${filter} on collection: ${collection}`);
|
||||||
|
|
||||||
const records = await pb.collection(collection).getList(1, limit, {
|
const records = await pb.collection(collection).getList(1, limit, {
|
||||||
sort: '-timestamp',
|
sort: '-timestamp',
|
||||||
@@ -199,7 +199,7 @@ export const uptimeService = {
|
|||||||
$cancelKey: `regional_uptime_history_${serviceId}_${Date.now()}`
|
$cancelKey: `regional_uptime_history_${serviceId}_${Date.now()}`
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Retrieved ${records.items.length} regional uptime records from ${collection} for region ${regionName}, agent ${agentId}`);
|
// console.log(`Retrieved ${records.items.length} regional uptime records from ${collection} for region ${regionName}, agent ${agentId}`);
|
||||||
|
|
||||||
const uptimeData = records.items.map(item => ({
|
const uptimeData = records.items.map(item => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
@@ -224,7 +224,7 @@ export const uptimeService = {
|
|||||||
return uptimeData;
|
return uptimeData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const collectionForError = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data';
|
const collectionForError = serviceType ? getCollectionForServiceType(serviceType) : 'uptime_data';
|
||||||
console.error(`Error fetching regional uptime history from ${collectionForError}:`, error);
|
// console.error(`Error fetching regional uptime history from ${collectionForError}:`, error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const convertToUserType = (record: any, role: string = "admin"): User => {
|
|||||||
export const userService = {
|
export const userService = {
|
||||||
async getUsers(): Promise<User[] | null> {
|
async getUsers(): Promise<User[] | null> {
|
||||||
try {
|
try {
|
||||||
console.log("Calling getUsers API");
|
// console.log("Calling getUsers API");
|
||||||
|
|
||||||
// Get both regular users and superadmins
|
// Get both regular users and superadmins
|
||||||
const regularUsers = await pb.collection('users').getList(1, 50, {
|
const regularUsers = await pb.collection('users').getList(1, 50, {
|
||||||
@@ -71,9 +71,9 @@ export const userService = {
|
|||||||
superadminUsers = await pb.collection('_superusers').getList(1, 50, {
|
superadminUsers = await pb.collection('_superusers').getList(1, 50, {
|
||||||
sort: 'created',
|
sort: 'created',
|
||||||
});
|
});
|
||||||
console.log("Successfully fetched superadmin users:", superadminUsers);
|
// console.log("Successfully fetched superadmin users:", superadminUsers);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("No superadmin collection or access rights:", error);
|
// console.log("No superadmin collection or access rights:", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine both user types and mark superadmins
|
// Combine both user types and mark superadmins
|
||||||
@@ -82,39 +82,39 @@ export const userService = {
|
|||||||
...superadminUsers.items.map((user: any) => convertToUserType(user, "superadmin"))
|
...superadminUsers.items.map((user: any) => convertToUserType(user, "superadmin"))
|
||||||
];
|
];
|
||||||
|
|
||||||
console.log("Combined users list:", allUsers);
|
// console.log("Combined users list:", allUsers);
|
||||||
|
|
||||||
return allUsers;
|
return allUsers;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch users:", error);
|
// console.error("Failed to fetch users:", error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async getUser(id: string): Promise<User | null> {
|
async getUser(id: string): Promise<User | null> {
|
||||||
try {
|
try {
|
||||||
console.log(`Fetching user with ID: ${id}`);
|
// console.log(`Fetching user with ID: ${id}`);
|
||||||
|
|
||||||
// Try fetching from regular users first
|
// Try fetching from regular users first
|
||||||
try {
|
try {
|
||||||
const user = await pb.collection('users').getOne(id);
|
const user = await pb.collection('users').getOne(id);
|
||||||
console.log("User fetch result (regular user):", user);
|
// console.log("User fetch result (regular user):", user);
|
||||||
return convertToUserType(user, user.role || "admin");
|
return convertToUserType(user, user.role || "admin");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("User not found in regular users, trying superadmin collection");
|
// console.log("User not found in regular users, trying superadmin collection");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not found, try in superadmins
|
// If not found, try in superadmins
|
||||||
try {
|
try {
|
||||||
const user = await pb.collection('_superusers').getOne(id);
|
const user = await pb.collection('_superusers').getOne(id);
|
||||||
console.log("User fetch result (superadmin):", user);
|
// console.log("User fetch result (superadmin):", user);
|
||||||
return convertToUserType(user, "superadmin");
|
return convertToUserType(user, "superadmin");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("User not found in superadmin collection either");
|
// console.log("User not found in superadmin collection either");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to fetch user ${id}:`, error);
|
// console.error(`Failed to fetch user ${id}:`, error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -130,11 +130,11 @@ export const userService = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Updating user with clean data:", cleanData);
|
// console.log("Updating user with clean data:", cleanData);
|
||||||
|
|
||||||
// If there's nothing to update, return the current user
|
// If there's nothing to update, return the current user
|
||||||
if (Object.keys(cleanData).length === 0) {
|
if (Object.keys(cleanData).length === 0) {
|
||||||
console.log("No changes to update");
|
// console.log("No changes to update");
|
||||||
const currentUser = await this.getUser(id);
|
const currentUser = await this.getUser(id);
|
||||||
return currentUser;
|
return currentUser;
|
||||||
}
|
}
|
||||||
@@ -197,16 +197,16 @@ export const userService = {
|
|||||||
await pb.collection('_superusers').delete(id);
|
await pb.collection('_superusers').delete(id);
|
||||||
updatedUser = convertToUserType(newRegularUser, "admin");
|
updatedUser = convertToUserType(newRegularUser, "admin");
|
||||||
}
|
}
|
||||||
console.log("User transferred between collections due to role change");
|
// console.log("User transferred between collections due to role change");
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to transfer user between collections:", error);
|
// console.error("Failed to transfer user between collections:", error);
|
||||||
throw new Error("Failed to change user role: " + (error instanceof Error ? error.message : "Unknown error"));
|
throw new Error("Failed to change user role: " + (error instanceof Error ? error.message : "Unknown error"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Regular update without changing collections
|
// Regular update without changing collections
|
||||||
if (Object.keys(cleanData).length > 0) {
|
if (Object.keys(cleanData).length > 0) {
|
||||||
console.log("Final update payload to PocketBase:", cleanData);
|
// console.log("Final update payload to PocketBase:", cleanData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Use the appropriate collection
|
// Use the appropriate collection
|
||||||
@@ -214,15 +214,15 @@ export const userService = {
|
|||||||
const updatedRecord = await pb.collection(collection).update(id, cleanData);
|
const updatedRecord = await pb.collection(collection).update(id, cleanData);
|
||||||
updatedUser = convertToUserType(updatedRecord, isCurrentlySuperadmin ? "superadmin" : "admin");
|
updatedUser = convertToUserType(updatedRecord, isCurrentlySuperadmin ? "superadmin" : "admin");
|
||||||
|
|
||||||
console.log("PocketBase update response:", updatedUser);
|
// console.log("PocketBase update response:", updatedUser);
|
||||||
|
|
||||||
// If email was updated successfully, show success message
|
// If email was updated successfully, show success message
|
||||||
if (hasEmailChange) {
|
if (hasEmailChange) {
|
||||||
console.log("Email updated successfully to:", emailToUpdate);
|
// console.log("Email updated successfully to:", emailToUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error updating user:", error);
|
// console.error("Error updating user:", error);
|
||||||
|
|
||||||
// Provide more specific error messages for email issues
|
// Provide more specific error messages for email issues
|
||||||
if (hasEmailChange && error instanceof Error) {
|
if (hasEmailChange && error instanceof Error) {
|
||||||
@@ -241,7 +241,7 @@ export const userService = {
|
|||||||
|
|
||||||
return updatedUser;
|
return updatedUser;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to update user:", error);
|
// console.error("Failed to update user:", error);
|
||||||
throw error; // Re-throw to handle in the component
|
throw error; // Re-throw to handle in the component
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -253,7 +253,7 @@ export const userService = {
|
|||||||
await pb.collection('users').delete(id);
|
await pb.collection('users').delete(id);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("User not found in regular users, trying superadmin collection");
|
// console.log("User not found in regular users, trying superadmin collection");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not found, try deleting from superadmin collection
|
// If not found, try deleting from superadmin collection
|
||||||
@@ -261,11 +261,11 @@ export const userService = {
|
|||||||
await pb.collection('_superusers').delete(id);
|
await pb.collection('_superusers').delete(id);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to delete user from either collection:", error);
|
// console.error("Failed to delete user from either collection:", error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to delete user:", error);
|
// console.error("Failed to delete user:", error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -282,7 +282,7 @@ export const userService = {
|
|||||||
if (cleanData.avatar.startsWith('http') ||
|
if (cleanData.avatar.startsWith('http') ||
|
||||||
cleanData.avatar.startsWith('/upload/') ||
|
cleanData.avatar.startsWith('/upload/') ||
|
||||||
cleanData.avatar.includes('api.dicebear.com')) {
|
cleanData.avatar.includes('api.dicebear.com')) {
|
||||||
console.log("Removing avatar URL for new user creation:", cleanData.avatar);
|
// console.log("Removing avatar URL for new user creation:", cleanData.avatar);
|
||||||
delete cleanData.avatar;
|
delete cleanData.avatar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,18 +291,18 @@ export const userService = {
|
|||||||
const isSuperAdmin = cleanData.role === "superadmin";
|
const isSuperAdmin = cleanData.role === "superadmin";
|
||||||
const collection = isSuperAdmin ? '_superusers' : 'users';
|
const collection = isSuperAdmin ? '_superusers' : 'users';
|
||||||
|
|
||||||
console.log(`Creating new user in ${collection} collection with data:`, {
|
/// console.log(`Creating new user in ${collection} collection with data:`, {
|
||||||
...cleanData,
|
// ...cleanData,
|
||||||
password: "[REDACTED]",
|
// password: "[REDACTED]",
|
||||||
passwordConfirm: "[REDACTED]"
|
// passwordConfirm: "[REDACTED]"
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Create the user in the appropriate collection
|
// Create the user in the appropriate collection
|
||||||
const result = await pb.collection(collection).create(cleanData);
|
const result = await pb.collection(collection).create(cleanData);
|
||||||
|
|
||||||
return convertToUserType(result, isSuperAdmin ? "superadmin" : "admin");
|
return convertToUserType(result, isSuperAdmin ? "superadmin" : "admin");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to create user:", error);
|
// console.error("Failed to create user:", error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user