]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[WebUI] Rework file upload JS implementation 5483/head
authorAlexander Moisseev <moiseev@mezonplus.ru>
Mon, 26 May 2025 10:04:30 +0000 (13:04 +0300)
committerAlexander Moisseev <moiseev@mezonplus.ru>
Mon, 26 May 2025 10:04:30 +0000 (13:04 +0300)
Original code, which seems AI-generated, was broken

Closes #5381

interface/js/app/common.js
interface/js/app/selectors.js
interface/js/app/upload.js

index b5d3cbbab91b4f19003596cf6e287226bac8de24..44e0dcf7788291d1389f747da667dab8f7f3919d 100644 (file)
@@ -262,53 +262,42 @@ define(["jquery", "nprogress"],
         };
 
         ui.fileUtils = {
-            files: null,
-            filesIdx: 0,
-
-            enableButton(button, textArea, validator) {
-                const hasText = $.trim($(textArea).val()).length > 0;
-                const needsValidation = validator !== "none";
-
-                $(button).prop("disabled", !hasText || (needsValidation && !$(validator).hasClass("is-valid")));
-            },
-
-            readFile(callback, textArea, button, validator) {
-                if (!this.files || this.files.length === 0) {
-                    alertMessage("alert-error", "No files selected.");
-                    return;
-                }
-
+            readFile(files, callback, index = 0) {
+                const file = files[index];
                 const reader = new FileReader();
-
-                reader.onload = () => {
-                    $(textArea).val(reader.result).trigger("input");
-                    this.enableButton(button, textArea, validator);
-
-                    if (callback) callback(reader.result);
-                };
-                reader.onerror = () => alertMessage("alert-error", "Error reading file.");
-                reader.readAsText(this.files[this.filesIdx]);
+                reader.onerror = () => alertMessage("alert-error", `Error reading file: ${file.name}`);
+                reader.onloadend = () => callback(reader.result);
+                reader.readAsText(file);
             },
 
-            handleFileInput(fileSrc, textArea, button, fileInput, validator) {
-                ({
-                    files: this.files
-                } = fileSrc);
-                this.filesIdx = 0;
-
-                if (!this.files.length) {
-                    alertMessage("alert-warning", "No file was provided.");
-                    return;
-                }
-                $(fileInput)[0].files = this.files;
-                // eslint-disable-next-line no-alert
-                if (this.files.length === 1 || confirm(`Are you sure you want to process ${this.files.length} files?`)) {
-                    this.readFile(null, textArea, button, validator);
-                }
+            setFileInputFiles(fileInput, files, i) {
+                const dt = new DataTransfer();
+                if (arguments.length > 2) dt.items.add(files[i]);
+                $(fileInput).prop("files", dt.files);
             },
 
-            setupFileHandling(textArea, fileInput, button, validator) {
+            setupFileHandling(textArea, fileInput, fileSet, enable_btn_cb, multiple_files_cb) {
                 const dragoverClassList = "outline-dashed-primary bg-primary-subtle";
+                const {readFile, setFileInputFiles} = ui.fileUtils;
+
+                function handleFileInput(fileSource) {
+                    fileSet.files = fileSource.files;
+                    fileSet.index = 0;
+                    const {files} = fileSet;
+
+                    if (files.length === 1) {
+                        setFileInputFiles(fileInput, files, 0);
+                        enable_btn_cb();
+                        readFile(files, (result) => {
+                            $(textArea).val(result);
+                            enable_btn_cb();
+                        });
+                    } else if (multiple_files_cb) {
+                        multiple_files_cb(files);
+                    } else {
+                        alertMessage("alert-warning", "Multiple files processing is not supported.");
+                    }
+                }
 
                 $(textArea)
                     .on("dragenter dragover dragleave drop", (e) => {
@@ -317,11 +306,16 @@ define(["jquery", "nprogress"],
                     })
                     .on("dragenter dragover", () => $(textArea).addClass(dragoverClassList))
                     .on("dragleave drop", () => $(textArea).removeClass(dragoverClassList))
-                    .on("drop", (e) => {
-                        this.handleFileInput(e.originalEvent.dataTransfer, textArea, button, fileInput, validator);
+                    .on("drop", (e) => handleFileInput(e.originalEvent.dataTransfer))
+                    .on("input", () => {
+                        enable_btn_cb();
+                        if (fileSet.files) {
+                            fileSet.files = null;
+                            setFileInputFiles(fileInput, fileSet.files);
+                        }
                     });
-                $(fileInput).on("change", (e) => this.handleFileInput(e.target, textArea, button, fileInput, validator));
-                $(textArea).on("input", () => this.enableButton(button, textArea, validator));
+
+                $(fileInput).on("change", (e) => handleFileInput(e.target));
             }
         };
 
index 788ceeacb680899e9de11ff045fd65ac93bf06ed..4a1c6d0d058992c59ef0415aeac921fe369da56a 100644 (file)
@@ -2,6 +2,7 @@ define(["jquery", "app/common"],
     ($, common) => {
         "use strict";
         const ui = {};
+        const fileSet = {files: null, index: null};
 
         function enable_disable_check_btn() {
             $("#selectorsChkMsgBtn").prop("disabled", (
@@ -129,9 +130,6 @@ define(["jquery", "app/common"],
             return false;
         });
 
-        $("#selectorsMsgArea").on("input", () => {
-            enable_disable_check_btn();
-        });
         $("#selectorsSelArea").on("input", () => {
             checkSelectors();
         });
@@ -140,7 +138,7 @@ define(["jquery", "app/common"],
             $("#selectorsFile").val("");
         });
 
-        common.fileUtils.setupFileHandling("#selectorsMsgArea", "#selectorsFile", "#selectorsChkMsgBtn", "#selectorsSelArea");
+        common.fileUtils.setupFileHandling("#selectorsMsgArea", "#selectorsFile", fileSet, enable_disable_check_btn);
 
         return ui;
     });
index 2ba4b616796c83a5a9bbf7547f190b72c2d82115..a5d30b59efc42ba9a597d0f7288798c13c34185f 100644 (file)
@@ -28,8 +28,7 @@ define(["jquery", "app/common", "app/libft"],
     ($, common, libft) => {
         "use strict";
         const ui = {};
-        let filesIdx = null;
-        let files = null;
+        const fileSet = {files: null, index: null};
         let scanTextHeaders = {};
 
         function uploadText(data, url, headers, method = "POST") {
@@ -67,15 +66,7 @@ define(["jquery", "app/common", "app/libft"],
 
         function enable_disable_scan_btn(disable) {
             $("#scan button:not(#cleanScanHistory, #deleteHashesBtn, #scanOptionsToggle, .ft-columns-btn)")
-                .prop("disabled", (disable || $.trim($("textarea").val()).length === 0));
-        }
-
-        function updateFileInput(i) {
-            const dt = new DataTransfer();
-            if (arguments.length > 0 && files && files[i]) {
-                dt.items.add(files[i]);
-            }
-            $("#formFile").prop("files", dt.files);
+                .prop("disabled", (disable || $.trim($("#scanMsgSource").val()).length === 0));
         }
 
         function scanText(data) {
@@ -96,7 +87,7 @@ define(["jquery", "app/common", "app/libft"],
                         const {items} = o;
                         common.symbols.scan.push(o.symbols[0]);
 
-                        if (files) items[0].file = files[filesIdx].name;
+                        if (fileSet.files) items[0].file = fileSet.files[fileSet.index].name;
 
                         if (Object.prototype.hasOwnProperty.call(common.tables, "scan")) {
                             common.tables.scan.rows.load(items, true);
@@ -104,16 +95,16 @@ define(["jquery", "app/common", "app/libft"],
                             require(["footable"], () => {
                                 libft.initHistoryTable(data, items, "scan", libft.columns_v2("scan"), true,
                                     () => {
-                                        if (files && filesIdx < files.length - 1) {
-                                            common.fileUtils.files = files;
-                                            common.fileUtils.filesIdx = ++filesIdx;
-                                            common.fileUtils.readFile((result) => {
-                                                if (filesIdx === files.length - 1) {
+                                        const {files} = fileSet;
+                                        if (files && fileSet.index < files.length - 1) {
+                                            common.fileUtils.readFile(files, (result) => {
+                                                const {index} = fileSet;
+                                                if (index === files.length - 1) {
                                                     $("#scanMsgSource").val(result);
-                                                    updateFileInput(filesIdx);
+                                                    common.fileUtils.setFileInputFiles("#formFile", files, index);
                                                 }
                                                 scanText(result);
-                                            }, "#scanMsgSource", "#scanCheckMsgBtn", "none");
+                                            }, ++fileSet.index);
                                         } else {
                                             enable_disable_scan_btn();
                                             $("#cleanScanHistory, #scan .ft-columns-dropdown .btn-dropdown-apply")
@@ -146,7 +137,6 @@ define(["jquery", "app/common", "app/libft"],
             });
         }
 
-
         function getFuzzyHashes(data) {
             function fillHashTable(rules) {
                 $("#hashTable tbody").empty();
@@ -186,8 +176,7 @@ define(["jquery", "app/common", "app/libft"],
         $("#cleanScanHistory").off("click");
         $("#cleanScanHistory").on("click", (e) => {
             e.preventDefault();
-            // eslint-disable-next-line no-alert
-            if (!confirm("Are you sure you want to clean scan history?")) {
+            if (!confirm("Are you sure you want to clean scan history?")) { // eslint-disable-line no-alert
                 return;
             }
             libft.destroyTable("scan");
@@ -196,13 +185,6 @@ define(["jquery", "app/common", "app/libft"],
         });
 
         enable_disable_scan_btn();
-        $("textarea").on("input", () => {
-            enable_disable_scan_btn();
-            if (files) {
-                files = null;
-                updateFileInput();
-            }
-        });
 
         $("#scanClean").on("click", () => {
             enable_disable_scan_btn(true);
@@ -304,7 +286,15 @@ define(["jquery", "app/common", "app/libft"],
         });
 
 
-        common.fileUtils.setupFileHandling("#scanMsgSource", "#formFile", "#scanCheckMsgBtn", "none");
+        function multiple_files_cb(files) {
+            // eslint-disable-next-line no-alert
+            if (files.length < 10 || confirm("Are you sure you want to scan " + files.length + " files?")) {
+                getScanTextHeaders();
+                common.fileUtils.readFile(files, (result) => scanText(result));
+            }
+        }
+
+        common.fileUtils.setupFileHandling("#scanMsgSource", "#formFile", fileSet, enable_disable_scan_btn, multiple_files_cb);
 
         return ui;
     });