]> git.giorgioravera.it Git - network-manager.git/commitdiff
Right click to copy logs
authorGiorgio Ravera <giorgio.ravera@gmail.com>
Thu, 18 Jun 2026 16:11:04 +0000 (18:11 +0200)
committerGiorgio Ravera <giorgio.ravera@gmail.com>
Thu, 18 Jun 2026 16:11:04 +0000 (18:11 +0200)
TODO.md
frontend/js/logs.js

diff --git a/TODO.md b/TODO.md
index 8978c734324402f50f0204fdcb1c4bef02c19cd9..844e6d234f1581e0791358111e16350398bc54ce 100644 (file)
--- a/TODO.md
+++ b/TODO.md
 
 ---
 
+## 📝 Logs
+
+- [x] Log Generation
+- [x] Application Log Visualization
+- [x] Access Log Visualization
+- [ ] DNS Log Visualization
+- [ ] DHCP Log Visualization
+- [X] Live Log Streaming
+- [ ] Log Filtering by Level
+- [ ] Time Range Filtering
+- [X] Multi-Row Selection
+- [ ] Export Logs (CSV/TXT)
+- [X] Copy Selected Logs (right click on selected)
+- [X] Auto Scroll (tail -f)
+
+---
+
 ## 🧩 Configuration Generation
 
 ### 🧪 BIND (DNS)
index 06b124eb3a5fe680e2712a79c2bcaacc7e19ea4e..5e1bf77b9c985f242a286a25bb394cfeab21d2cc 100644 (file)
@@ -144,9 +144,26 @@ function renderLogs(text, isNearBottom, previousScroll, previousHeight) {
                 lastSelectedRowId = rowId;
             });
 
-            // double click to copy
-            div.addEventListener("dblclick", async () => {
-                await navigator.clipboard.writeText(line);
+
+            // right click to copy logs
+            div.addEventListener("contextmenu", async (e) => {
+
+                e.preventDefault();
+
+                // se la riga non è selezionata la seleziono
+                if (!selectedRows.has(rowId)) {
+
+                    selectedRows.clear();
+
+                    document
+                        .querySelectorAll(".log-row.selected")
+                        .forEach(r => r.classList.remove("selected"));
+
+                    selectedRows.add(rowId);
+                    div.classList.add("selected");
+                }
+
+                await copySelectedLogs();
             });
 
             div.innerHTML =
@@ -185,6 +202,42 @@ function renderLogs(text, isNearBottom, previousScroll, previousHeight) {
     }
 }
 
+// -----------------------------
+// copy logs
+// -----------------------------
+async function copySelectedLogs() {
+
+    const rows = Array.from(document.querySelectorAll(".log-row"));
+
+    const selectedTexts = rows
+        .filter(row => selectedRows.has(row.dataset.rowId))
+        .map(row => row.textContent.trim());
+
+    if (!selectedTexts.length) {
+        showToast("No rows selected", false);
+        return;
+    }
+
+    try {
+
+        await navigator.clipboard.writeText(
+            selectedTexts.join("\n")
+        );
+
+        showToast(
+            `${selectedTexts.length} log(s) copied`,
+            true
+        );
+
+    } catch (err) {
+
+        showToast(
+            "Error copying logs",
+            false
+        );
+    }
+}
+
 // -----------------------------
 // update dropdown menu
 // -----------------------------