mirror of
https://github.com/StarFleetCPTN/GoMFT.git
synced 2026-09-08 15:41:20 +02:00
refactor: Remove log generator functionality and update UI components
- Eliminated the log generator feature from the admin logs template and related handlers. - Updated icons in the log viewer for consistency and improved visual clarity. - Adjusted mobile dropdown functionality in the layout template for better user experience. - Cleaned up debug logging statements in the WebSocket handler for recent logs.
This commit is contained in:
@@ -28,7 +28,7 @@ templ AdminLogs(ctx context.Context, data LogViewerData) {
|
|||||||
<!-- Page Header -->
|
<!-- Page Header -->
|
||||||
<div class="mb-6 flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
<div class="mb-6 flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
||||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white flex items-center">
|
<h1 class="text-2xl font-bold text-gray-900 dark:text-white flex items-center">
|
||||||
<i class="fas fa-file-alt w-6 h-6 mr-2 text-blue-500 dark:text-blue-400"></i> Log Viewer
|
<i class="fas fa-stream w-6 h-6 mr-2 text-blue-500 dark:text-blue-400"></i> Log Viewer
|
||||||
</h1>
|
</h1>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<button id="pause-logs" class="flex items-center justify-center text-white bg-yellow-500 hover:bg-yellow-600 focus:ring-4 focus:ring-yellow-300 font-medium rounded-lg px-4 py-2 dark:bg-yellow-600 dark:hover:bg-yellow-700 focus:outline-none dark:focus:ring-yellow-800">
|
<button id="pause-logs" class="flex items-center justify-center text-white bg-yellow-500 hover:bg-yellow-600 focus:ring-4 focus:ring-yellow-300 font-medium rounded-lg px-4 py-2 dark:bg-yellow-600 dark:hover:bg-yellow-700 focus:outline-none dark:focus:ring-yellow-800">
|
||||||
@@ -43,9 +43,6 @@ templ AdminLogs(ctx context.Context, data LogViewerData) {
|
|||||||
<button id="download-logs" class="flex items-center justify-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">
|
<button id="download-logs" class="flex items-center justify-center text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">
|
||||||
<i class="fas fa-download w-4 h-4 mr-2"></i> Download
|
<i class="fas fa-download w-4 h-4 mr-2"></i> Download
|
||||||
</button>
|
</button>
|
||||||
<button id="start-generator" class="flex items-center justify-center text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg px-4 py-2 dark:bg-purple-600 dark:hover:bg-purple-700 focus:outline-none dark:focus:ring-purple-800">
|
|
||||||
<i class="fas fa-cogs w-4 h-4 mr-2"></i> Start Log Generator
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -150,7 +147,6 @@ templ AdminLogs(ctx context.Context, data LogViewerData) {
|
|||||||
const resumeButton = document.getElementById('resume-logs');
|
const resumeButton = document.getElementById('resume-logs');
|
||||||
const clearButton = document.getElementById('clear-logs');
|
const clearButton = document.getElementById('clear-logs');
|
||||||
const downloadButton = document.getElementById('download-logs');
|
const downloadButton = document.getElementById('download-logs');
|
||||||
const generatorButton = document.getElementById('start-generator');
|
|
||||||
const connectionStatus = document.getElementById('connection-status');
|
const connectionStatus = document.getElementById('connection-status');
|
||||||
const filterLevel = document.getElementById('filter-level');
|
const filterLevel = document.getElementById('filter-level');
|
||||||
const filterSource = document.getElementById('filter-source');
|
const filterSource = document.getElementById('filter-source');
|
||||||
@@ -512,33 +508,6 @@ templ AdminLogs(ctx context.Context, data LogViewerData) {
|
|||||||
searchTimeout = setTimeout(applyFilters, 300);
|
searchTimeout = setTimeout(applyFilters, 300);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start Log Generator button click
|
|
||||||
generatorButton.addEventListener('click', function() {
|
|
||||||
fetch('/admin/logs/start-generator', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
console.log(data.message);
|
|
||||||
// Show toast or notification
|
|
||||||
const toast = document.createElement('div');
|
|
||||||
toast.className = 'fixed bottom-4 right-4 bg-green-500 text-white px-4 py-2 rounded-lg shadow-lg z-50';
|
|
||||||
toast.innerHTML = 'Log generator started';
|
|
||||||
document.body.appendChild(toast);
|
|
||||||
|
|
||||||
// Remove toast after 3 seconds
|
|
||||||
setTimeout(() => {
|
|
||||||
toast.remove();
|
|
||||||
}, 3000);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error starting log generator:', error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initial connection
|
// Initial connection
|
||||||
connectWebSocket();
|
connectWebSocket();
|
||||||
});
|
});
|
||||||
|
|||||||
+27
-3
@@ -194,7 +194,7 @@ templ LayoutWithContext(title string, ctx context.Context) {
|
|||||||
Audit Logs
|
Audit Logs
|
||||||
</a>
|
</a>
|
||||||
<a href="/admin/logs" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700">
|
<a href="/admin/logs" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700">
|
||||||
<i class="fas fa-file-alt w-4 h-4 mr-2 text-gray-500 dark:text-gray-400"></i>
|
<i class="fas fa-stream w-4 h-4 mr-2 text-gray-500 dark:text-gray-400"></i>
|
||||||
Log Viewer
|
Log Viewer
|
||||||
</a>
|
</a>
|
||||||
<a href="/admin/database" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700">
|
<a href="/admin/database" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700">
|
||||||
@@ -297,19 +297,23 @@ templ LayoutWithContext(title string, ctx context.Context) {
|
|||||||
<i class="fas fa-clipboard-list w-4 h-4 mr-2 text-gray-500 dark:text-gray-400"></i>
|
<i class="fas fa-clipboard-list w-4 h-4 mr-2 text-gray-500 dark:text-gray-400"></i>
|
||||||
Audit Logs
|
Audit Logs
|
||||||
</a>
|
</a>
|
||||||
|
<a href="/admin/logs" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700">
|
||||||
|
<i class="fas fa-stream w-4 h-4 mr-2 text-gray-500 dark:text-gray-400"></i>
|
||||||
|
Log Viewer
|
||||||
|
</a>
|
||||||
<a href="/admin/database" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700">
|
<a href="/admin/database" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700">
|
||||||
<i class="fas fa-database w-4 h-4 mr-2 text-gray-500 dark:text-gray-400"></i>
|
<i class="fas fa-database w-4 h-4 mr-2 text-gray-500 dark:text-gray-400"></i>
|
||||||
Database Tools
|
Database Tools
|
||||||
</a>
|
</a>
|
||||||
// Settings Dropdown
|
// Settings Dropdown
|
||||||
<button type="button" class="flex items-center w-full p-2 text-base text-gray-900 transition duration-75 rounded-lg group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700" aria-controls="dropdown-settings" data-collapse-toggle="dropdown-settings">
|
<button type="button" class="flex items-center w-full p-2 text-base text-gray-900 transition duration-75 rounded-lg group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700" aria-controls="dropdown-settings-mobile" data-collapse-toggle="dropdown-settings-mobile">
|
||||||
<i class="fas fa-cog w-4 h-4 mr-2 text-gray-500 dark:text-gray-400"></i>
|
<i class="fas fa-cog w-4 h-4 mr-2 text-gray-500 dark:text-gray-400"></i>
|
||||||
<span class="flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">Settings</span>
|
<span class="flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">Settings</span>
|
||||||
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
||||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<ul id="dropdown-settings" class="hidden py-2 space-y-2">
|
<ul id="dropdown-settings-mobile" class="hidden py-2 space-y-2">
|
||||||
// <li>
|
// <li>
|
||||||
// <a href="#" class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700">General (Coming Soon)</a>
|
// <a href="#" class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700">General (Coming Soon)</a>
|
||||||
// </li>
|
// </li>
|
||||||
@@ -510,6 +514,26 @@ templ LayoutWithContext(title string, ctx context.Context) {
|
|||||||
<!-- Application scripts -->
|
<!-- Application scripts -->
|
||||||
<script defer src="/static/dist/app.js"></script>
|
<script defer src="/static/dist/app.js"></script>
|
||||||
<script defer src="/static/dist/init.js"></script>
|
<script defer src="/static/dist/init.js"></script>
|
||||||
|
<!-- Dropdown fix for mobile -->
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
// Initialize the mobile dropdown separately
|
||||||
|
const mobileDropdownButton = document.querySelector('[data-collapse-toggle="dropdown-settings-mobile"]');
|
||||||
|
const mobileDropdown = document.getElementById("dropdown-settings-mobile");
|
||||||
|
|
||||||
|
if (mobileDropdownButton && mobileDropdown) {
|
||||||
|
// Show dropdown if on admin pages
|
||||||
|
if (window.location.pathname.startsWith("/admin")) {
|
||||||
|
// Keep it hidden by default, will be toggled by button
|
||||||
|
mobileDropdown.classList.add("hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
mobileDropdownButton.addEventListener("click", function() {
|
||||||
|
mobileDropdown.classList.toggle("hidden");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1473,7 +1473,7 @@ func (h *Handlers) sendRecentLogs(ws *websocket.Conn) {
|
|||||||
fmt.Fprintf(os.Stderr, "[DEBUG-WS] Read %d lines from %s for client %v.\n", len(lines), logFilePath, ws.RemoteAddr())
|
fmt.Fprintf(os.Stderr, "[DEBUG-WS] Read %d lines from %s for client %v.\n", len(lines), logFilePath, ws.RemoteAddr())
|
||||||
|
|
||||||
// Parse and send each line as a log entry, protected by the client's mutex
|
// Parse and send each line as a log entry, protected by the client's mutex
|
||||||
for i, line := range lines {
|
for _, line := range lines {
|
||||||
level, source, message := parseLogLine(line)
|
level, source, message := parseLogLine(line)
|
||||||
timestamp := extractTimestamp(line)
|
timestamp := extractTimestamp(line)
|
||||||
|
|
||||||
@@ -1485,18 +1485,18 @@ func (h *Handlers) sendRecentLogs(ws *websocket.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use the specific client's mutex
|
// Use the specific client's mutex
|
||||||
fmt.Fprintf(os.Stderr, "[DEBUG-WS] Sending recent log %d/%d to client %v\n", i+1, len(lines), ws.RemoteAddr())
|
// fmt.Fprintf(os.Stderr, "[DEBUG-WS] Sending recent log %d/%d to client %v\n", i+1, len(lines), ws.RemoteAddr())
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
err := ws.WriteJSON(logEntry)
|
err := ws.WriteJSON(logEntry)
|
||||||
mutex.Unlock()
|
mutex.Unlock()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "[DEBUG-WS] Error sending recent log %d to client %v: %v. Stopping recent logs send.\n", i+1, ws.RemoteAddr(), err)
|
// fmt.Fprintf(os.Stderr, "[DEBUG-WS] Error sending recent log %d to client %v: %v. Stopping recent logs send.\n", i+1, ws.RemoteAddr(), err)
|
||||||
// Don't try to remove the client here, let the main read loop handle it
|
// Don't try to remove the client here, let the main read loop handle it
|
||||||
break // Stop sending recent logs on first error
|
break // Stop sending recent logs on first error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "[DEBUG-WS] Finished sending %d recent logs to client %v.\n", len(lines), ws.RemoteAddr())
|
// fmt.Fprintf(os.Stderr, "[DEBUG-WS] Finished sending %d recent logs to client %v.\n", len(lines), ws.RemoteAddr())
|
||||||
}
|
}
|
||||||
|
|
||||||
// readLastLines reads the last n lines from a file
|
// readLastLines reads the last n lines from a file
|
||||||
@@ -1722,30 +1722,3 @@ func (h *Handlers) sendExampleLogs(ws *websocket.Conn) {
|
|||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "[DEBUG-WS] Finished sending example logs to client %v.\n", ws.RemoteAddr())
|
fmt.Fprintf(os.Stderr, "[DEBUG-WS] Finished sending example logs to client %v.\n", ws.RemoteAddr())
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleStartLogGenerator handles requests to start the log generator for testing
|
|
||||||
func (h *Handlers) HandleStartLogGenerator(c *gin.Context) {
|
|
||||||
// Directly send a log to verify the WebSocket is working
|
|
||||||
h.BroadcastLog("info", "Starting log generator...", "test")
|
|
||||||
|
|
||||||
// Start a goroutine to generate some test logs
|
|
||||||
go func() {
|
|
||||||
logLevels := []string{"debug", "info", "warn", "error"}
|
|
||||||
sources := []string{"test", "generator", "system", "scheduler"}
|
|
||||||
|
|
||||||
// First, send a direct log message to all clients
|
|
||||||
for i := 0; i < 20; i++ {
|
|
||||||
level := logLevels[i%len(logLevels)]
|
|
||||||
source := sources[i%len(sources)]
|
|
||||||
message := fmt.Sprintf("Test log entry #%d generated at %s", i+1, time.Now().Format(time.RFC3339))
|
|
||||||
|
|
||||||
// First directly broadcast without going through normal logging
|
|
||||||
h.BroadcastLog(level, message, source)
|
|
||||||
|
|
||||||
// Wait a short time between logs
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": "Log generator started"})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -132,9 +132,11 @@ func (h *Handlers) RegisterRoutes(router *gin.Engine) {
|
|||||||
{
|
{
|
||||||
adminRoles.GET("", h.HandleRoles)
|
adminRoles.GET("", h.HandleRoles)
|
||||||
adminRoles.GET("/new", h.HandleNewRole)
|
adminRoles.GET("/new", h.HandleNewRole)
|
||||||
|
adminRoles.GET("/:id", h.HandleEditRole)
|
||||||
adminRoles.GET("/:id/edit", h.HandleRoles)
|
adminRoles.GET("/:id/edit", h.HandleRoles)
|
||||||
adminRoles.POST("", h.HandleCreateRole)
|
adminRoles.POST("", h.HandleCreateRole)
|
||||||
adminRoles.PUT("/:id", h.HandleEditRole)
|
adminRoles.POST("/:id", h.HandleUpdateRole)
|
||||||
|
adminRoles.PUT("/:id", h.HandleUpdateRole)
|
||||||
adminRoles.DELETE("/:id", h.HandleDeleteRole)
|
adminRoles.DELETE("/:id", h.HandleDeleteRole)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +154,6 @@ func (h *Handlers) RegisterRoutes(router *gin.Engine) {
|
|||||||
{
|
{
|
||||||
logsGroup.GET("", h.HandleLogViewer)
|
logsGroup.GET("", h.HandleLogViewer)
|
||||||
logsGroup.GET("/ws", h.HandleLogStream)
|
logsGroup.GET("/ws", h.HandleLogStream)
|
||||||
logsGroup.POST("/start-generator", h.HandleStartLogGenerator)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// System settings routes
|
// System settings routes
|
||||||
|
|||||||
@@ -66,9 +66,6 @@ func main() {
|
|||||||
// Set Gin to release mode
|
// Set Gin to release mode
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
|
||||||
// Initialize random for test log generator (Go 1.20+ compatible)
|
|
||||||
// No need to seed in newer Go versions as it's automatically initialized
|
|
||||||
|
|
||||||
// Initialize configuration
|
// Initialize configuration
|
||||||
cfg, err := config.Load()
|
cfg, err := config.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user