]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] Fix hover behavior for Status tab tables
authorAlexander Moisseev <moiseev@mezonplus.ru>
Tue, 11 Nov 2025 13:32:10 +0000 (16:32 +0300)
committerAlexander Moisseev <moiseev@mezonplus.ru>
Tue, 11 Nov 2025 13:32:10 +0000 (16:32 +0300)
Tables with rowspan cells (Bayesian statistics and Fuzzy hashes)
now have consistent hover highlighting across all rows in a group.

interface/css/rspamd.css
interface/js/app/stats.js

index a43f1e5e1c31982f1a21c0ddf688e8614c59ab41..367b96066cdeba1a7f604704adb0e5715696fcda 100644 (file)
@@ -346,10 +346,10 @@ table#symbolsTable input[type="number"] {
 .symbol-special {
     background-color: var(--rspamd-symbol-special-bg);
 }
-.symbol-negative:hover {
+.parent:not(.status-table) .symbol-negative:hover {
     background-color: var(--rspamd-symbol-hover-bg);
 }
-.symbol-positive:hover {
+.parent:not(.status-table) .symbol-positive:hover {
     background-color: var(--rspamd-symbol-hover-bg);
 }
 .symbol-special:hover {
@@ -428,6 +428,12 @@ table#symbolsTable input[type="number"] {
     border-radius: 0 0 0 calc(var(--bs-border-radius) + 1px);
 }
 
+/* Hover effect for table cells in tables with rowspan groups */
+.status-table tbody td.table-hover-cell {
+    --bs-table-color-state: var(--bs-table-hover-color);
+    --bs-table-bg-state: var(--bs-table-hover-bg);
+}
+
 /* RRD summary */
 #summary-row {
     padding-left: 80px;
index e504aef799737b7c0dc8261a268fd3c6c6cc8ef9..e97b704af0b8199ea6d61e4381eca6896b19ea8d 100644 (file)
@@ -55,6 +55,51 @@ define(["jquery", "app/common", "d3pie", "d3"],
             return out;
         }
 
+        let rowspanHoverHandlersInitialized = false;
+
+        function attachRowspanHoverHandlers(tableId) {
+            const $table = $(tableId);
+
+            function findRowspanCell($row) {
+                const headerCount = $table.find("thead th").length;
+                if ($row.find("td").length >= headerCount) return null;
+
+                // Assumes rowspan cells always appear in the first column
+                let result = null;
+                $row.prevAll().find("td:first-child[rowspan]").each((_, el) => {
+                    const $cell = $(el);
+                    const rowspan = parseInt($cell.attr("rowspan"), 10);
+                    const distance = $row.prevAll().length - $cell.parent().prevAll().length;
+                    if (distance < rowspan) {
+                        result = $cell;
+                        return false; // break
+                    }
+                    return true;
+                });
+                return result;
+            }
+
+            $table.on("mouseenter", "tbody td", (event) => {
+                const $cell = $(event.currentTarget);
+                const $row = $cell.parent();
+
+                if ($cell.attr("rowspan")) {
+                    // Hovering over rowspan cell - highlight entire group
+                    const rowspan = parseInt($cell.attr("rowspan"), 10);
+                    $cell.addClass("table-hover-cell");
+                    $row.find("td").addClass("table-hover-cell");
+                    $row.nextAll().slice(0, rowspan - 1).find("td").addClass("table-hover-cell");
+                } else {
+                    // Hovering over regular cell - highlight current row
+                    $row.find("td").addClass("table-hover-cell");
+
+                    // Highlight rowspan cell if exists
+                    const $rowspanCell = findRowspanCell($row);
+                    if ($rowspanCell) $rowspanCell.addClass("table-hover-cell");
+                }
+            }).on("mouseleave", "tbody td", () => $table.find("tbody td").removeClass("table-hover-cell"));
+        }
+
         function displayStatWidgets(checked_server) {
             const servers = JSON.parse(sessionStorage.getItem("Credentials"));
             let data = {};
@@ -223,6 +268,12 @@ define(["jquery", "app/common", "d3pie", "d3"],
                 addStatfiles(checked_server, data.statfiles);
                 addFuzzyStorage(checked_server, data.fuzzy_hashes);
             }
+
+            if (!rowspanHoverHandlersInitialized) {
+                attachRowspanHoverHandlers("#bayesTable");
+                attachRowspanHoverHandlers("#fuzzyTable");
+                rowspanHoverHandlersInitialized = true;
+            }
         }
 
         function getChart(graphs, checked_server) {