Update AppImage

This commit is contained in:
MacRimi
2025-10-12 19:51:03 +02:00
parent 44d54057d0
commit 9666bee006
2 changed files with 56 additions and 35 deletions

View File

@@ -993,30 +993,28 @@ export function SystemLogs() {
{/* Notifications Tab */} {/* Notifications Tab */}
<TabsContent value="notifications" className="space-y-4"> <TabsContent value="notifications" className="space-y-4">
<ScrollArea className="h-[600px] w-full rounded-md border border-border"> <ScrollArea className="h-[600px] w-full rounded-md border border-border">
<div className="space-y-2 p-4"> <div className="space-y-2 p-2 sm:p-4">
{notifications.map((notification, index) => ( {notifications.map((notification, index) => (
<div <div
key={index} key={index}
className="flex flex-col md:flex-row md:items-start space-y-2 md:space-y-0 md:space-x-4 p-3 rounded-lg bg-card/50 border border-border/50 hover:bg-card/80 transition-colors cursor-pointer" className="flex flex-col space-y-2 p-2 sm:p-3 rounded-lg bg-card/50 border border-border/50 hover:bg-card/80 transition-colors cursor-pointer"
onClick={() => { onClick={() => {
setSelectedNotification(notification) setSelectedNotification(notification)
setIsNotificationModalOpen(true) setIsNotificationModalOpen(true)
}} }}
> >
<div className="flex-shrink-0 flex items-center gap-2"> <div className="flex items-center gap-2 flex-wrap">
{getNotificationIcon(notification.type)} {getNotificationIcon(notification.type)}
<Badge variant="outline" className={getNotificationTypeColor(notification.type)}> <Badge variant="outline" className={`${getNotificationTypeColor(notification.type)} text-xs`}>
{notification.type.toUpperCase()} {notification.type.toUpperCase()}
</Badge> </Badge>
<div className="text-xs text-muted-foreground font-mono ml-auto whitespace-nowrap">
{notification.timestamp}
</div>
</div> </div>
<div className="flex-1 min-w-0"> <div className="space-y-1">
<div className="flex items-center justify-between mb-1"> <div className="text-sm text-foreground line-clamp-2 break-words">{notification.message}</div>
<div className="text-xs text-muted-foreground font-mono whitespace-nowrap ml-2">
{notification.timestamp}
</div>
</div>
<div className="text-sm text-foreground mb-1 line-clamp-2">{notification.message}</div>
<div className="text-xs text-muted-foreground truncate"> <div className="text-xs text-muted-foreground truncate">
Service: {notification.service} Source: {notification.source} Service: {notification.service} Source: {notification.source}
</div> </div>
@@ -1223,51 +1221,55 @@ export function SystemLogs() {
</Dialog> </Dialog>
<Dialog open={isNotificationModalOpen} onOpenChange={setIsNotificationModalOpen}> <Dialog open={isNotificationModalOpen} onOpenChange={setIsNotificationModalOpen}>
<DialogContent className="max-w-3xl max-h-[80vh] overflow-y-auto"> <DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto w-[95vw] sm:w-full">
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center gap-2"> <DialogTitle className="flex items-center gap-2 text-base sm:text-lg">
<Bell className="h-5 w-5" /> <Bell className="h-4 w-4 sm:h-5 sm:w-5" />
Notification Details Notification Details
</DialogTitle> </DialogTitle>
<DialogDescription>Complete information about this notification</DialogDescription> <DialogDescription className="text-xs sm:text-sm">
Complete information about this notification
</DialogDescription>
</DialogHeader> </DialogHeader>
{selectedNotification && ( {selectedNotification && (
<div className="space-y-4"> <div className="space-y-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-3 sm:gap-4">
<div> <div>
<div className="text-sm font-medium text-muted-foreground mb-1">Type</div> <div className="text-xs sm:text-sm font-medium text-muted-foreground mb-1">Type</div>
<Badge variant="outline" className={getNotificationTypeColor(selectedNotification.type)}> <Badge variant="outline" className={`${getNotificationTypeColor(selectedNotification.type)} text-xs`}>
{selectedNotification.type.toUpperCase()} {selectedNotification.type.toUpperCase()}
</Badge> </Badge>
</div> </div>
<div className="sm:col-span-2"> <div>
<div className="text-sm font-medium text-muted-foreground mb-1">Timestamp</div> <div className="text-xs sm:text-sm font-medium text-muted-foreground mb-1">Timestamp</div>
<div className="text-sm text-foreground font-mono break-words">{selectedNotification.timestamp}</div> <div className="text-xs sm:text-sm text-foreground font-mono break-words">
{selectedNotification.timestamp}
</div>
</div> </div>
<div> <div>
<div className="text-sm font-medium text-muted-foreground mb-1">Service</div> <div className="text-xs sm:text-sm font-medium text-muted-foreground mb-1">Service</div>
<div className="text-sm text-foreground break-words">{selectedNotification.service}</div> <div className="text-xs sm:text-sm text-foreground break-words">{selectedNotification.service}</div>
</div> </div>
<div> <div>
<div className="text-sm font-medium text-muted-foreground mb-1">Source</div> <div className="text-xs sm:text-sm font-medium text-muted-foreground mb-1">Source</div>
<div className="text-sm text-foreground break-words">{selectedNotification.source}</div> <div className="text-xs sm:text-sm text-foreground break-words">{selectedNotification.source}</div>
</div> </div>
</div> </div>
<div> <div>
<div className="text-sm font-medium text-muted-foreground mb-2">Message</div> <div className="text-xs sm:text-sm font-medium text-muted-foreground mb-2">Message</div>
<div className="p-4 rounded-lg bg-muted/50 border border-border max-h-[300px] overflow-y-auto"> <div className="p-3 sm:p-4 rounded-lg bg-muted/50 border border-border max-h-[200px] sm:max-h-[300px] overflow-y-auto">
<pre className="text-sm text-foreground whitespace-pre-wrap break-words"> <pre className="text-xs sm:text-sm text-foreground whitespace-pre-wrap break-words">
{selectedNotification.message} {selectedNotification.message}
</pre> </pre>
</div> </div>
</div> </div>
<div className="flex justify-end"> <div className="flex justify-end pt-2">
<Button <Button
variant="outline" variant="outline"
onClick={() => handleDownloadNotificationLog(selectedNotification)} onClick={() => handleDownloadNotificationLog(selectedNotification)}
className="border-border w-full sm:w-auto" className="border-border w-full sm:w-auto text-xs sm:text-sm"
> >
<Download className="h-4 w-4 mr-2" /> <Download className="h-3 w-3 sm:h-4 sm:w-4 mr-2" />
Download Complete Message Download Complete Message
</Button> </Button>
</div> </div>

View File

@@ -3814,8 +3814,8 @@ def get_task_log(upid):
node = parts[1] node = parts[1]
starttime = parts[4] starttime = parts[4]
# Calculate index (last character of starttime in hex) # Calculate index (last character of starttime in hex, lowercase)
index = starttime[-1].upper() index = starttime[-1].lower()
print(f"[v0] Extracted node: {node}, starttime: {starttime}, index: {index}") print(f"[v0] Extracted node: {node}, starttime: {starttime}, index: {index}")
@@ -3831,8 +3831,27 @@ def get_task_log(upid):
print(f"[v0] Successfully read {len(log_text)} bytes from log file") print(f"[v0] Successfully read {len(log_text)} bytes from log file")
return log_text, 200, {'Content-Type': 'text/plain; charset=utf-8'} return log_text, 200, {'Content-Type': 'text/plain; charset=utf-8'}
else: else:
print(f"[v0] Log file not found: {log_file_path}") # Try with uppercase index
return jsonify({'error': 'Log file not found'}), 404 log_file_path_upper = f"/var/log/pve/tasks/{index.upper()}/{upid}"
print(f"[v0] Trying alternative path: {log_file_path_upper}")
if os.path.exists(log_file_path_upper):
with open(log_file_path_upper, 'r', encoding='utf-8', errors='ignore') as f:
log_text = f.read()
print(f"[v0] Successfully read {len(log_text)} bytes from alternative log file")
return log_text, 200, {'Content-Type': 'text/plain; charset=utf-8'}
else:
# List available files in the directory for debugging
tasks_dir = f"/var/log/pve/tasks/{index}"
if os.path.exists(tasks_dir):
available_files = os.listdir(tasks_dir)
print(f"[v0] Available files in {tasks_dir}: {available_files[:10]}") # Show first 10
else:
print(f"[v0] Tasks directory does not exist: {tasks_dir}")
print(f"[v0] Log file not found: {log_file_path}")
return jsonify({'error': 'Log file not found', 'path': log_file_path}), 404
except Exception as e: except Exception as e:
print(f"[v0] Error fetching task log for UPID {upid}: {type(e).__name__}: {e}") print(f"[v0] Error fetching task log for UPID {upid}: {type(e).__name__}: {e}")