admin firs step

This commit is contained in:
Roo
2026-03-23 21:43:40 +00:00
parent 309a72cc0b
commit cddcd34ba9
47 changed files with 22698 additions and 19 deletions

190
complete_ailogs.py Normal file
View File

@@ -0,0 +1,190 @@
#!/usr/bin/env python3
import os
# Read the existing file
with open('frontend/admin/components/AiLogsTile.vue', 'r') as f:
content = f.read()
# Find where the file is truncated
if 'case \'success\': return \'green' in content and not 'case \'warning\': return \'orange\'' in content:
# The file is truncated at the getLogColor function
# Let's find the exact position and complete it
lines = content.split('\n')
# Find the line with getLogColor
for i, line in enumerate(lines):
if 'const getLogColor = (type: AiLogEntry[\'type\']) => {' in line:
start_idx = i
# Find where this function ends (look for the next function or end of file)
for j in range(i+1, len(lines)):
if lines[j].strip().startswith('const ') or lines[j].strip().startswith('//'):
# Found next function or comment
end_idx = j
break
else:
end_idx = len(lines)
# Replace the incomplete function with complete version
new_function = '''const getLogColor = (type: AiLogEntry['type']) => {
switch (type) {
case 'info': return 'blue'
case 'success': return 'green'
case 'warning': return 'orange'
case 'error': return 'red'
case 'gold': return 'amber'
default: return 'grey'
}
}
const getLogIcon = (type: AiLogEntry['type']) => {
switch (type) {
case 'info': return 'mdi-information'
case 'success': return 'mdi-check-circle'
case 'warning': return 'mdi-alert'
case 'error': return 'mdi-alert-circle'
case 'gold': return 'mdi-star'
default: return 'mdi-help-circle'
}
}
const getRobotColor = (robotName: string) => {
const robot = robots.value.find(r => r.name === robotName)
return robot?.statusColor || 'grey'
}
const getStatusColor = (status: string) => {
switch (status.toLowerCase()) {
case 'running': return 'success'
case 'idle': return 'warning'
case 'error': return 'error'
case 'paused': return 'grey'
default: return 'grey'
}
}
const formatTime = (timestamp: Date) => {
const now = new Date()
const diff = now.getTime() - timestamp.getTime()
if (diff < 60000) return 'Just now'
if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`
if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`
return timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
}
// Data fetching and polling
const fetchLogs = async () => {
if (isRefreshing.value) return
isRefreshing.value = true
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 500))
// Add new mock log
const newLog = generateMockLog()
logs.value.push(newLog)
// Keep only last 50 logs
if (logs.value.length > 50) {
logs.value = logs.value.slice(-50)
}
// Mark old logs as not new
setTimeout(() => {
logs.value.forEach(log => {
if (log.isNew && Date.now() - log.timestamp.getTime() > 5000) {
log.isNew = false
}
})
}, 5000)
// Update connection status randomly
if (Math.random() > 0.95) {
connectionStatus.value = 'disconnected'
} else if (Math.random() > 0.98) {
connectionStatus.value = 'error'
} else {
connectionStatus.value = 'connected'
}
} catch (error) {
console.error('Failed to fetch AI logs:', error)
connectionStatus.value = 'error'
} finally {
isRefreshing.value = false
isLoading.value = false
}
}
const forceRefresh = () => {
fetchLogs()
}
const toggleAutoScroll = () => {
autoScroll.value = !autoScroll.value
}
const clearLogs = () => {
logs.value = []
}
const scrollToBottom = () => {
if (logContainer.value && autoScroll.value) {
nextTick(() => {
logContainer.value!.scrollTop = logContainer.value!.scrollHeight
})
}
}
// Polling management
let pollInterval: number | null = null
const startPolling = () => {
if (pollInterval) clearInterval(pollInterval)
pollInterval = setInterval(() => {
fetchLogs()
scrollToBottom()
}, pollingInterval.value) as unknown as number
}
const stopPolling = () => {
if (pollInterval) {
clearInterval(pollInterval)
pollInterval = null
}
}
// Lifecycle hooks
onMounted(() => {
// Initial load
fetchLogs()
// Start polling
startPolling()
// Generate initial logs
for (let i = 0; i < 10; i++) {
const log = generateMockLog()
log.timestamp = new Date(Date.now() - (10 - i) * 60000) // Staggered times
log.isNew = false
logs.value.push(log)
}
isLoading.value = false
})
onUnmounted(() => {
stopPolling()
})'''
# Replace the lines
new_lines = lines[:start_idx] + new_function.split('\n')
content = '\n'.join(new_lines)
break
# Write the complete file
with open('frontend/admin/components/AiLogsTile.vue', 'w') as f:
f.write(content)
print("File completed successfully")