]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Rework] Refactor element visibility control to use Bootstrap classes 5675/head
authorCopilot <198982749+Copilot@users.noreply.github.com>
Fri, 10 Oct 2025 17:17:41 +0000 (20:17 +0300)
committerGitHub <noreply@github.com>
Fri, 10 Oct 2025 17:17:41 +0000 (20:17 +0300)
Replace inline styles and mixed jQuery methods with consistent helper functions and `d-none` class for better maintainability and performance.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: moisseev <2275981+moisseev@users.noreply.github.com>
interface/index.html
interface/js/app/common.js
interface/js/app/config.js
interface/js/app/history.js
interface/js/app/libft.js
interface/js/app/rspamd.js
interface/js/app/stats.js
interface/js/app/upload.js

index 165eae200b2967a49c13be83c60e7138dbae676b..1cd49203e15d4a8f47263ae5fb30523dbcb9c762 100644 (file)
@@ -48,8 +48,8 @@
 
                                <li role="presentation" class="nav-item"><a id="configuration_nav" aria-controls="configuration" role="tab" href="#configuration" data-bs-toggle="tab" class="nav-link">Configuration</a></li>
                                <li role="presentation" class="nav-item"><a id="symbols_nav" aria-controls="symbols" role="tab" href="#symbols" data-bs-toggle="tab" class="nav-link">Symbols</a></li>
-                               <li role="presentation" class="nav-item"><a id="scan_nav" aria-controls="scan" role="tab" href="#scan" data-bs-toggle="tab" class="nav-link">Scan<span class="ro-hide" style="display: none;">/Learn</span></a></li>
-                               <li role="presentation" class="nav-item"><a id="selectors_nav" aria-controls="selectors" role="tab" href="#selectors" data-bs-toggle="tab" class="nav-link ro-hide" style="display: none;">Test selectors</a></li>
+                               <li role="presentation" class="nav-item"><a id="scan_nav" aria-controls="scan" role="tab" href="#scan" data-bs-toggle="tab" class="nav-link">Scan<span class="ro-hide d-none">/Learn</span></a></li>
+                               <li role="presentation" class="nav-item"><a id="selectors_nav" aria-controls="selectors" role="tab" href="#selectors" data-bs-toggle="tab" class="nav-link ro-hide d-none">Test selectors</a></li>
                                <li role="presentation" class="nav-item"><a id="history_nav" aria-controls="history" role="tab" href="#history" data-bs-toggle="tab" class="nav-link">History</a></li>
                        </ul>
                </div>
                <div class="tab-content">
                        <div class="tab-pane" id="status">
                                <div class="row">
-                                       <div id="statWidgets" class="col-lg-12 stat-boxes fw-bold text-secondary" style="display: none;">
+                                       <div id="statWidgets" class="col-lg-12 stat-boxes fw-bold text-secondary d-none">
                                        </div>
                                </div>
                                <div class="row">
                                                </div>
                                        </div>
                                </div>
-                               <div class="card ro-hide" style="display: none;">
+                               <div class="card ro-hide d-none">
                                        <div class="card-header text-secondary py-1 d-flex align-items-center">
                                                <span class="icon me-3"><i class="fas fa-graduation-cap"></i></span>
                                                <span class="h6 fw-bolder my-auto">Learn Rspamd</span>
                                        </div>
                                </div>
 
-                               <div id="hash-card" class="card bg-light shadow my-3" style="display: none;">
+                               <div id="hash-card" class="card bg-light shadow my-3 d-none">
                                        <div class="card-header text-secondary py-2 d-flex align-items-center">
                                                <span class="icon me-3"><i class="fas fa-hashtag"></i></span>
                                                <span class="h6 fw-bolder my-auto">Fuzzy hashes</span>
                                                <span class="h6 fw-bolder my-auto ms-0">History</span>
                                                <a href="https://rspamd.com/doc/modules/history_redis.html" target="_blank" rel="noopener noreferrer"
                                                        title="If you'd like to use the modern version of History, please enable History redis module."
-                                                        id="legacy-history-badge" class="my-2 ms-2 badge text-bg-info" style="display: none;">Legacy version</a>
+                                                        id="legacy-history-badge" class="my-2 ms-2 badge text-bg-info d-none">Legacy version</a>
                                                <div class="d-flex input-group-sm align-items-center text-nowrap ms-auto me-1">
                                                        <label for="selSymOrder_history">Symbols order:</label>
                                                        <select id="selSymOrder_history" class="form-select ms-1">
                                            Browser detects passwords by form.elements[n].type == "password" and then detects
                                                the username field by searching backwards through form elements for the text field
                                                immediately before the password fields. -->
-                                       <input value="Rspamd controller password" style="display: none;"/>
+                                       <input value="Rspamd controller password" class="d-none"/>
                                        <div class="input-group">
                                                <input class="form-control"
                                                           type="password"
index 6f37d739e88424a909b9a1275a8ea48c7efb7ea1..86c01273ca6f05a055e709abb64085837dc2ed75 100644 (file)
@@ -284,6 +284,50 @@ define(["jquery", "nprogress"],
             return String(string).replace(htmlEscaper, (match) => htmlEscapes[match]);
         };
 
+        /**
+         * Hide one or more elements using Bootstrap's d-none class
+         * @param {string|jQuery} selector - CSS selector or jQuery object
+         * @param {boolean} anim - Whether to use animation (slideUp)
+         */
+        ui.hide = function (selector, anim = false) {
+            const $el = (typeof selector === "string") ? $(selector) : selector;
+            if (anim) {
+                $el.slideUp(400, function () {
+                    $(this).addClass("d-none");
+                });
+            } else {
+                $el.addClass("d-none");
+            }
+        };
+
+        /**
+         * Show one or more elements using Bootstrap's d-none class
+         * @param {string|jQuery} selector - CSS selector or jQuery object
+         * @param {boolean} anim - Whether to use animation (slideDown)
+         */
+        ui.show = function (selector, anim = false) {
+            const $el = (typeof selector === "string") ? $(selector) : selector;
+            if (anim) {
+                $el.removeClass("d-none").hide().slideDown(400);
+            } else {
+                $el.removeClass("d-none");
+            }
+        };
+
+        /**
+         * Toggle visibility of one or more elements using Bootstrap's d-none class
+         * @param {string|jQuery} selector - CSS selector or jQuery object
+         * @param {boolean} anim - Whether to use animation
+         */
+        ui.toggle = function (selector, anim = false) {
+            const $el = (typeof selector === "string") ? $(selector) : selector;
+            if ($el.hasClass("d-none")) {
+                ui.show($el, anim);
+            } else {
+                ui.hide($el, anim);
+            }
+        };
+
         ui.appendButtonsToFtFilterDropdown = (ftFilter) => {
             function button(text, classes, check) {
                 return $("<button/>", {
index 57e7ee37b8f0a7713bf38598ef971bf8bf20a89d..65a3f5e877d08b97dca24229c4630999567ee059 100644 (file)
@@ -111,7 +111,7 @@ define(["jquery", "app/common"],
 
         ui.getMaps = function () {
             const $listmaps = $("#listMaps");
-            $listmaps.closest(".card").hide();
+            common.hide($listmaps.closest(".card"));
             common.query("maps", {
                 success: function (json) {
                     const [{data}] = json;
@@ -137,7 +137,7 @@ define(["jquery", "app/common"],
                         $("<td>" + item.description + "</td>").appendTo($tr);
                         $tr.appendTo($tbody);
                     });
-                    $listmaps.closest(".card").show();
+                    common.show($listmaps.closest(".card"));
                 },
                 server: common.getServer()
             });
@@ -191,9 +191,9 @@ define(["jquery", "app/common"],
                     if (item.editable === false || common.read_only) {
                         $("#editor").attr(editor[mode].readonly_attr);
                         icon = "fa-eye";
-                        $("#modalSaveGroup").hide();
+                        common.hide("#modalSaveGroup");
                     } else {
-                        $("#modalSaveGroup").show();
+                        common.show("#modalSaveGroup");
                     }
                     $("#modalDialog .modal-header").find("[data-fa-i2svg]").addClass(icon);
                     $("#modalTitle").html(item.uri);
index bf1dbae534f283d879054062d6c18c6e44eb4df7..2ed8d5605fcb0e4aaed13ffbec531e91796bbefb 100644 (file)
@@ -41,7 +41,7 @@ define(["jquery", "app/common", "app/libft", "footable"],
 
             function compare(e1, e2) { return e1.name.localeCompare(e2.name); }
 
-            $("#selSymOrder_history, label[for='selSymOrder_history']").hide();
+            common.hide("#selSymOrder_history, label[for='selSymOrder_history']");
 
             $.each(data, (i, item) => {
                 item.time = libft.unix_time_format(item.unix_time);
@@ -181,11 +181,11 @@ define(["jquery", "app/common", "app/libft", "footable"],
                             data.rows = [].concat.apply([], neighbours_data
                                 .map((e) => e.rows));
                             data.version = version;
-                            $("#legacy-history-badge").hide();
+                            common.hide("#legacy-history-badge");
                         } else {
                             // Legacy version
                             data = [].concat.apply([], neighbours_data);
-                            $("#legacy-history-badge").show();
+                            common.show("#legacy-history-badge");
                         }
                         const o = process_history_data(data);
                         const {items} = o;
index ca2a1ebef2e17bd1dd5a0324ff4dca069ed5569e..29d2dcc41d8666ac6ee8aed20c201d601588c547 100644 (file)
@@ -539,7 +539,7 @@ define(["jquery", "app/common", "footable"],
             const unsorted_symbols = [];
             const compare_function = get_compare_function(table);
 
-            $("#selSymOrder_" + table + ", label[for='selSymOrder_" + table + "']").show();
+            common.show("#selSymOrder_" + table + ", label[for='selSymOrder_" + table + "]");
 
             $.each(data.rows,
                 (i, item) => {
index 4b154c2ae471daea38fa94c448ba5615d2e83e9f..0434549ef1754ed710ec5e0c6aff0c929d2cde1e 100644 (file)
@@ -139,9 +139,9 @@ define(["jquery", "app/common", "stickytabs", "visibility",
                         () => module.statWidgets(graphs, checked_server));
                     if (id !== "#autoRefresh") module.statWidgets(graphs, checked_server);
 
-                    $(".preset").show();
-                    $(".history").hide();
-                    $(".dynamic").hide();
+                    common.show(".preset");
+                    common.hide(".history");
+                    common.hide(".dynamic");
                 });
                 break;
             case "#throughput_nav":
@@ -161,9 +161,9 @@ define(["jquery", "app/common", "stickytabs", "visibility",
                         () => module.draw(graphs, common.neighbours, checked_server, selData));
                     if (id !== "#autoRefresh") module.draw(graphs, common.neighbours, checked_server, selData);
 
-                    $(".preset").hide();
-                    $(".history").hide();
-                    $(".dynamic").show();
+                    common.hide(".preset");
+                    common.hide(".history");
+                    common.show(".dynamic");
                 });
                 break;
             case "#configuration_nav":
@@ -195,9 +195,9 @@ define(["jquery", "app/common", "stickytabs", "visibility",
                         () => getHistoryAndErrors());
                     if (id !== "#autoRefresh") getHistoryAndErrors();
 
-                    $(".preset").hide();
-                    $(".history").show();
-                    $(".dynamic").hide();
+                    common.hide(".preset");
+                    common.show(".history");
+                    common.hide(".dynamic");
 
                     module.updateHistoryControlsState();
                 });
@@ -245,10 +245,10 @@ define(["jquery", "app/common", "stickytabs", "visibility",
 
                 if (common.read_only) {
                     $(".ro-disable").attr("disabled", true);
-                    $(".ro-hide").hide();
+                    common.hide(".ro-hide");
                 } else {
                     $(".ro-disable").removeAttr("disabled", true);
-                    $(".ro-hide").show();
+                    common.show(".ro-hide");
                 }
 
                 $("#preloader").addClass("d-none");
@@ -280,7 +280,7 @@ define(["jquery", "app/common", "stickytabs", "visibility",
             error: function () {
                 function clearFeedback() {
                     $("#connectPassword").off("input").removeClass("is-invalid");
-                    $("#authInvalidCharFeedback,#authUnauthorizedFeedback").hide();
+                    common.hide("#authInvalidCharFeedback,#authUnauthorizedFeedback");
                 }
 
                 $("#connectDialog")
@@ -302,7 +302,7 @@ define(["jquery", "app/common", "stickytabs", "visibility",
                         $("#connectPassword")
                             .addClass("is-invalid")
                             .off("input").on("input", () => clearFeedback());
-                        $(tooltip).show();
+                        common.show(tooltip);
                     }
 
                     if (!(/^[\u0020-\u007e]*$/).test(password)) {
index 8ac4eacddd20ea5c35d4a6f2df1b4dfc8c3b025a..d7510b163a721a6d66bd2d986e86dcf28a3b4d2f 100644 (file)
@@ -63,7 +63,8 @@ define(["jquery", "app/common", "d3pie", "d3"],
             }
 
             const stat_w = [];
-            $("#statWidgets").empty().hide();
+            $("#statWidgets").empty();
+            common.hide("#statWidgets");
             $.each(data, (i, item) => {
                 const widgetsOrder = ["scanned", "no action", "greylist", "add header", "rewrite subject", "reject", "learned"];
 
@@ -102,7 +103,7 @@ define(["jquery", "app/common", "d3pie", "d3"],
                 .wrapAll('<div class="card stat-box text-center shadow-sm float-end">' +
                   '<div class="widget overflow-hidden p-2 text-capitalize"></div></div>');
             $("#statWidgets").find("div.float-end").appendTo("#statWidgets");
-            $("#statWidgets").show();
+            common.show("#statWidgets");
 
             $("#clusterTable tbody").empty();
             $("#selSrv").empty();
index a3bb973634d83339b166f27d1fd134df090262fa..69a0e20d8042585c2688ba39aa302ec565990539 100644 (file)
@@ -151,7 +151,7 @@ define(["jquery", "app/common", "app/libft"],
                           "<td>" + hash + "</td></tr>");
                     });
                 }
-                $("#hash-card").slideDown();
+                common.show("#hash-card", true);
             }
 
             common.query("plugins/fuzzy/hashes?flag=" + $("#fuzzy-flag").val(), {
@@ -198,7 +198,7 @@ define(["jquery", "app/common", "app/libft"],
         });
 
         $(".card-close-btn").on("click", function () {
-            $(this).closest(".card").slideUp();
+            common.hide($(this).closest(".card"), true);
         });
 
         function getScanTextHeaders() {
@@ -364,8 +364,8 @@ define(["jquery", "app/common", "app/libft"],
 
         function toggleWidgets(showPicker, showInput) {
             fuzzyWidgets.forEach(({picker, input}) => {
-                $(picker)[showPicker ? "show" : "hide"]();
-                $(input)[showInput ? "show" : "hide"]();
+                (showPicker ? common.show : common.hide)(picker);
+                (showInput ? common.show : common.hide)(input);
             });
         }
 
@@ -418,8 +418,8 @@ define(["jquery", "app/common", "app/libft"],
                             const $picker = $(picker);
                             $picker
                                 .empty()
-                                .append($("<option>", {value: "", text: "fuzzy_check disabled"}))
-                                .show();
+                                .append($("<option>", {value: "", text: "fuzzy_check disabled"}));
+                            common.show($picker);
                             container($picker)
                                 .attr("title", "fuzzy_check module is not enabled in server configuration.");
                         });