commit 4b07085: [WebUI] Disable buttons until tables are ready

moisseev moiseev at mezonplus.ru
Mon Jul 29 17:52:55 UTC 2024


Author: moisseev
Date: 2024-02-25 17:59:02 +0300
URL: https://github.com/rspamd/rspamd/commit/4b07085920b53b71c08d6471089b0eb2ae4c7ed7 (refs/pull/4838/head)

[WebUI] Disable buttons until tables are ready
to prevent race conditions

---
 interface/js/app/history.js |  6 ++++--
 interface/js/app/libft.js   | 19 +++----------------
 interface/js/app/symbols.js | 10 ++++++++--
 interface/js/app/upload.js  | 41 ++++++++++++++++-------------------------
 4 files changed, 31 insertions(+), 45 deletions(-)

diff --git a/interface/js/app/history.js b/interface/js/app/history.js
index 0d953ec1e..a429b21ca 100644
--- a/interface/js/app/history.js
+++ b/interface/js/app/history.js
@@ -151,6 +151,7 @@ define(["jquery", "app/common", "app/libft", "footable"],
         }
 
         ui.getHistory = function () {
+            $("#refresh, #updateHistory").attr("disabled", true);
             common.query("history", {
                 success: function (req_data) {
                     function differentVersions(neighbours_data) {
@@ -190,7 +191,8 @@ define(["jquery", "app/common", "app/libft", "footable"],
                             libft.destroyTable("history");
                             // Is there a way to get an event when the table is destroyed?
                             setTimeout(() => {
-                                libft.initHistoryTable(data, items, "history", get_history_columns(data), false);
+                                libft.initHistoryTable(data, items, "history", get_history_columns(data), false,
+                                    () => $("#refresh, #updateHistory").removeAttr("disabled"));
                             }, 200);
                         }
                         prevVersion = version;
@@ -198,7 +200,7 @@ define(["jquery", "app/common", "app/libft", "footable"],
                         libft.destroyTable("history");
                     }
                 },
-                complete: function () { $("#refresh").removeAttr("disabled").removeClass("disabled"); },
+                error: () => $("#refresh, #updateHistory").removeAttr("disabled"),
                 errorMessage: "Cannot receive history",
             });
         };
diff --git a/interface/js/app/libft.js b/interface/js/app/libft.js
index 14ef458f6..1e9cbf9a1 100644
--- a/interface/js/app/libft.js
+++ b/interface/js/app/libft.js
@@ -231,7 +231,7 @@ define(["jquery", "app/common", "footable"],
             }
         };
 
-        ui.initHistoryTable = function (data, items, table, columns, expandFirst) {
+        ui.initHistoryTable = function (data, items, table, columns, expandFirst, postdrawCallback) {
             /* eslint-disable no-underscore-dangle */
             FooTable.Cell.extend("collapse", function () {
                 // call the original method
@@ -339,7 +339,8 @@ define(["jquery", "app/common", "footable"],
                             detail_row.find(".btn-sym-" + table + "-" + order)
                                 .addClass("active").siblings().removeClass("active");
                         }, 5);
-                    }
+                    },
+                    "postdraw.ft.table": postdrawCallback
                 }
             });
         };
@@ -508,19 +509,5 @@ define(["jquery", "app/common", "footable"],
             return {items: items, symbols: unsorted_symbols};
         };
 
-        ui.waitForRowsDisplayed = function (table, rows_total, callback, iteration) {
-            let i = (typeof iteration === "undefined") ? 10 : iteration;
-            const num_rows = $("#historyTable_" + table + " > tbody > tr:not(.footable-detail-row)").length;
-            if (num_rows === common.page_size[table] ||
-                num_rows === rows_total) {
-                return callback();
-            } else if (--i) {
-                setTimeout(() => {
-                    ui.waitForRowsDisplayed(table, rows_total, callback, i);
-                }, 500);
-            }
-            return null;
-        };
-
         return ui;
     });
diff --git a/interface/js/app/symbols.js b/interface/js/app/symbols.js
index 2d8f359fc..21d83b1c3 100644
--- a/interface/js/app/symbols.js
+++ b/interface/js/app/symbols.js
@@ -46,7 +46,7 @@ define(["jquery", "app/common", "footable"],
                     clear_altered();
                     common.alertMessage("alert-modal alert-success", "Symbols successfully saved");
                 },
-                complete: () => $("#save-alert button").removeAttr("disabled", true),
+                complete: () => $("#save-alert button").removeAttr("disabled"),
                 errorMessage: "Save symbols error",
                 method: "POST",
                 params: {
@@ -123,6 +123,7 @@ define(["jquery", "app/common", "footable"],
         }
         // @get symbols into modal form
         ui.getSymbols = function () {
+            $("#refresh, #updateSymbols").attr("disabled", true);
             clear_altered();
             common.query("symbols", {
                 success: function (json) {
@@ -216,10 +217,13 @@ define(["jquery", "app/common", "footable"],
                                 if (common.read_only) {
                                     $(".mb-disabled").attr("disabled", true);
                                 }
-                            }
+                            },
+                            "postdraw.ft.table":
+                                () => $("#refresh, #updateSymbols").removeAttr("disabled")
                         }
                     });
                 },
+                error: () => $("#refresh, #updateSymbols").removeAttr("disabled"),
                 server: common.getServer()
             });
         };
@@ -227,12 +231,14 @@ define(["jquery", "app/common", "footable"],
 
         $("#updateSymbols").on("click", (e) => {
             e.preventDefault();
+            $("#refresh, #updateSymbols").attr("disabled", true);
             clear_altered();
             common.query("symbols", {
                 success: function (data) {
                     const [items] = process_symbols_data(data[0].data);
                     common.tables.symbols.rows.load(items);
                 },
+                error: () => $("#refresh, #updateSymbols").removeAttr("disabled"),
                 server: common.getServer()
             });
         });
diff --git a/interface/js/app/upload.js b/interface/js/app/upload.js
index dc1bf1c9c..a27dc8a88 100644
--- a/interface/js/app/upload.js
+++ b/interface/js/app/upload.js
@@ -33,7 +33,6 @@ define(["jquery", "app/common", "app/libft"],
             $("#" + source + "TextSource").val("");
         }
 
-        // @upload text
         function uploadText(data, source, headers) {
             let url = null;
             if (source === "spam") {
@@ -73,8 +72,13 @@ define(["jquery", "app/common", "app/libft"],
             });
         }
 
-        // @upload text
+        function enable_disable_scan_btn(disable) {
+            $("#scan button:not(#cleanScanHistory, #scanOptionsToggle)")
+                .prop("disabled", (disable || $.trim($("textarea").val()).length === 0));
+        }
+
         function scanText(data, headers) {
+            enable_disable_scan_btn(true);
             common.query("checkv2", {
                 data: data,
                 params: {
@@ -83,42 +87,33 @@ define(["jquery", "app/common", "app/libft"],
                 method: "POST",
                 headers: headers,
                 success: function (neighbours_status) {
-                    function scrollTop(rows_total) {
-                        // Is there a way to get an event when all rows are loaded?
-                        libft.waitForRowsDisplayed("scan", rows_total, () => {
-                            $("#cleanScanHistory").removeAttr("disabled", true);
-                            $("html, body").animate({
-                                scrollTop: $("#scanResult").offset().top
-                            }, 1000);
-                        });
-                    }
-
                     const json = neighbours_status[0].data;
                     if (json.action) {
                         common.alertMessage("alert-success", "Data successfully scanned");
 
-                        const rows_total = $("#historyTable_scan > tbody > tr:not(.footable-detail-row)").length + 1;
                         const o = libft.process_history_v2({rows: [json]}, "scan");
                         const {items} = o;
                         common.symbols.scan.push(o.symbols[0]);
 
                         if (Object.prototype.hasOwnProperty.call(common.tables, "scan")) {
                             common.tables.scan.rows.load(items, true);
-                            scrollTop(rows_total);
                         } else {
-                            libft.destroyTable("scan");
                             require(["footable"], () => {
-                                // Is there a way to get an event when the table is destroyed?
-                                setTimeout(() => {
-                                    libft.initHistoryTable(data, items, "scan", libft.columns_v2("scan"), true);
-                                    scrollTop(rows_total);
-                                }, 200);
+                                libft.initHistoryTable(data, items, "scan", libft.columns_v2("scan"), true,
+                                    () => {
+                                        enable_disable_scan_btn();
+                                        $("#cleanScanHistory").removeAttr("disabled");
+                                        $("html, body").animate({
+                                            scrollTop: $("#scanResult").offset().top
+                                        }, 1000);
+                                    });
                             });
                         }
                     } else {
                         common.alertMessage("alert-error", "Cannot scan data");
                     }
                 },
+                error: enable_disable_scan_btn,
                 errorMessage: "Cannot upload data",
                 statusCode: {
                     404: function () {
@@ -182,17 +177,13 @@ define(["jquery", "app/common", "app/libft"],
             $("#cleanScanHistory").attr("disabled", true);
         });
 
-        function enable_disable_scan_btn() {
-            $("#scan button:not(#cleanScanHistory, #scanOptionsToggle)")
-                .prop("disabled", ($.trim($("textarea").val()).length === 0));
-        }
         enable_disable_scan_btn();
         $("textarea").on("input", () => {
             enable_disable_scan_btn();
         });
 
         $("#scanClean").on("click", () => {
-            $("#scan button:not(#cleanScanHistory, #scanOptionsToggle)").attr("disabled", true);
+            enable_disable_scan_btn(true);
             $("#scanForm")[0].reset();
             $("html, body").animate({scrollTop: 0}, 1000);
             return false;


More information about the Commits mailing list