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);