diff --git a/docs/inputs.rst b/docs/inputs.rst index d87acd2203..fcbd02ff6f 100644 --- a/docs/inputs.rst +++ b/docs/inputs.rst @@ -16,6 +16,11 @@ Supported file types include archives (e.g., ``.tar``, ``.zip``, ``.tar.gz``), individual source files, pre-built packages, and **SBOMs** (SPDX or CycloneDX in JSON format). +.. note:: + + Uploading folders/directories is not supported. If you need to upload a folder, + create an archive (e.g., ``.zip`` or ``.tar.gz``) and upload the archive instead. + When uploading through the Web UI, navigate to your project and use the upload interface in the "Inputs" panel. diff --git a/scancodeio/static/add-inputs.js b/scancodeio/static/add-inputs.js index 0a99d1233a..29654faaeb 100644 --- a/scancodeio/static/add-inputs.js +++ b/scancodeio/static/add-inputs.js @@ -24,6 +24,9 @@ const fileInput = document.querySelector("#id_input_files"); let selectedFiles = []; // Store selected files fileInput.onchange = updateFiles; +// Handle drag and drop events +const inputFilesBox = document.querySelector("#input_files_box"); + // Update the list of files to be uploaded in the UI function updateFiles() { if (fileInput.files.length > 0) { @@ -33,14 +36,16 @@ function updateFiles() { // Update the selectedFiles array const newFiles = Array.from(fileInput.files); // Create a Set to track unique file names - const uniqueFileNames = new Set(selectedFiles.map(file => file.name)); + const uniqueFileNames = new Set(selectedFiles.map((file) => file.name)); // Filter out files with the same name - const filteredNewFiles = newFiles.filter(file => !uniqueFileNames.has(file.name)); + const filteredNewFiles = newFiles.filter( + (file) => !uniqueFileNames.has(file.name) + ); // Concatenate the unique files to the existing selectedFiles array selectedFiles = selectedFiles.concat(filteredNewFiles); for (let file of selectedFiles) { - const fileNameWithoutSpaces = file.name.replace(/\s/g, ''); + const fileNameWithoutSpaces = file.name.replace(/\s/g, ""); fileName.innerHTML += ` ${file.name} @@ -49,13 +54,15 @@ function updateFiles() { `; - document.getElementById("file-delete-btn-"+ fileNameWithoutSpaces).addEventListener("click", function(event){ - disableEvent(event); - removeFile(fileNameWithoutSpaces); - if(selectedFiles.length == 0){ - fileName.innerHTML ="No files selected" - } - }); + document + .getElementById("file-delete-btn-" + fileNameWithoutSpaces) + .addEventListener("click", function (event) { + disableEvent(event); + removeFile(fileNameWithoutSpaces); + if (selectedFiles.length == 0) { + fileName.innerHTML = "No files selected"; + } + }); } } } @@ -67,8 +74,8 @@ function disableEvent(event) { } function removeFile(fileName) { - selectedFiles = selectedFiles.filter(file => { - const fileNameWithoutSpaces = file.name.replace(/\s/g, ''); + selectedFiles = selectedFiles.filter((file) => { + const fileNameWithoutSpaces = file.name.replace(/\s/g, ""); return fileNameWithoutSpaces !== fileName; }); @@ -85,9 +92,53 @@ function removeFile(fileName) { fileInput.files = dataTransfer.files; } +function showFolderUploadNotSupportedMessage() { + let notice = document.querySelector("#folder-upload-notice"); + if (!notice) { + notice = document.createElement("div"); + notice.id = "folder-upload-notice"; + notice.className = "notification is-warning is-light mt-2"; + notice.innerHTML = ` + Folders are not supported. + Please upload a .zip or .tar.gz archive instead. + `; + inputFilesBox.insertAdjacentElement("afterend", notice); + } +} + function dropHandler(event) { disableEvent(event); - const droppedFiles = event.dataTransfer.files; + + const items = event.dataTransfer.items; + let droppedFiles = []; + let hasDirectory = false; + + if (items && items.length > 0) { + // Build a list of files from the dropped items, skipping directories + for (const item of items) { + const entry = item.webkitGetAsEntry?.(); + if (entry && entry.isDirectory) { + hasDirectory = true; + continue; + } + const file = item.getAsFile?.(); + if (file) { + droppedFiles.push(file); + } + } + } else { + // Fallback when items are not available + droppedFiles = Array.from(event.dataTransfer.files || []); + } + + if (hasDirectory) { + showFolderUploadNotSupportedMessage(); + } + + // If there are no files at all (e.g. only folders were dropped), do nothing further + if (droppedFiles.length === 0) { + return; + } const updatedFilesSet = new Set(Array.from(fileInput.files)); for (let file of droppedFiles) { @@ -106,8 +157,6 @@ function dropHandler(event) { updateFiles(); } -// Handle drag and drop events -const inputFilesBox = document.querySelector("#input_files_box"); inputFilesBox.addEventListener("dragenter", disableEvent); inputFilesBox.addEventListener("dragover", disableEvent); inputFilesBox.addEventListener("drop", dropHandler);