Files
xamxam/app/public/assets/js/file-upload-queue.js
Pontoporeia ca7707cd47 refactor: session-based incremental TFE upload via HTMX, drop SortableJS
Replace the client-side FileArray + Sortable drag-to-reorder with a
server-side session-based upload flow:

- New endpoints: /partage/upload-tfe-file, /partage/remove-tfe-file
  (and /admin/ variants) — single-file incremental upload via HTMX
  multipart/form-data with progress bar support
- Session storage: uploaded files go to STORAGE_ROOT/uploads/{session_id}/
  with metadata in $_SESSION['tfe_uploads']
- file-upload-queue.js reduced to single-file previews only (couverture,
  note_intention, annexes thumbnails)
- ThesisFileHandler gains handleTfeFilesFromSession + writeTfeFileFromSrc
  + cleanupSessionUploads for final commit from session temp
- Sortable.min.js removed from all script tags; drag handles and ghost
  CSS removed
- No file_orders[]/file_labels[] hidden field injection needed
- Upload queue survives page refresh (server-owned list)

This eliminates the SortableJS dependency entirely while keeping the
same UX: pick files, see them in a queue, remove individual files.
2026-05-19 00:08:05 +02:00

110 lines
3.2 KiB
JavaScript

/**
* file-upload-queue.js
*
* Provides single-file previews for file inputs with the data-preview attribute
* (couverture, note_intention, annexes, etc.).
*
* The multi-file TFE queue is rendered server-side via HTMX fragments
* (upload-tfe-file.php / remove-tfe-file.php).
*
* Exposes window.XamxamInitFileUploads() so HTMX fragments can re-bind
* after swap without a global event listener.
*/
window.XamxamInitFileUploads = function () {
console.log("[file-upload-queue] XamxamInitFileUploads called");
var ICON = {
pdf: "\uD83D\uDCC4",
video: "\uD83C\uDFAC",
audio: "\uD83D\uDD0A",
zip: "\uD83D\uDDDC\uFE0F",
vtt: "\uD83D\uDCAC",
image: "\uD83D\uDDBC\uFE0F",
other: "\uD83D\uDCCE",
};
function iconFor(file) {
var t = file.type || "",
n = file.name.toLowerCase();
if (/^image\//.test(t)) return ICON.image;
if (t === "application/pdf" || /\.pdf$/.test(n)) return ICON.pdf;
if (/^video\//.test(t) || /\.(mp4|webm|mov|ogv)$/.test(n))
return ICON.video;
if (/^audio\//.test(t) || /\.(mp3|ogg|oga|wav|flac|aac|m4a)$/.test(n))
return ICON.audio;
if (/\.(zip|tar|gz|tgz)$/.test(n)) return ICON.zip;
if (/\.vtt$/.test(n)) return ICON.vtt;
return ICON.other;
}
function humanSize(b) {
return b >= 1073741824
? (b / 1073741824).toFixed(2) + " GB"
: b >= 1048576
? (b / 1048576).toFixed(2) + " MB"
: b >= 1024
? (b / 1024).toFixed(1) + " KB"
: b + " B";
}
function esc(s) {
return s.replace(/[&<>"]/g, function (c) {
return { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c];
});
}
// ── Single-file previews (data-preview attribute) ────────────────────
document
.querySelectorAll('input[type="file"][data-preview]')
.forEach(function (input) {
if (input.id === "tfe-files-input") return;
console.log(
"[file-upload-queue] binding preview for",
input.id,
"multiple=",
input.multiple,
);
var container = document.getElementById(
input.getAttribute("data-preview"),
);
if (!container) return;
input.onchange = function () {
container.innerHTML = "";
Array.from(input.files).forEach(function (file) {
var item = document.createElement("div");
item.className = "fp-item";
if (/^image\//.test(file.type)) {
var img = document.createElement("img");
img.className = "fp-thumb";
img.alt = file.name;
var reader = new FileReader();
reader.onload = function (e) {
img.src = e.target.result;
};
reader.readAsDataURL(file);
item.appendChild(img);
} else {
var ic = document.createElement("span");
ic.className = "fp-icon";
ic.textContent = iconFor(file);
item.appendChild(ic);
}
var meta = document.createElement("span");
meta.className = "fp-meta";
meta.innerHTML =
'<span class="fp-name">' +
esc(file.name) +
'</span><span class="fp-size">' +
humanSize(file.size) +
"</span>";
item.appendChild(meta);
container.appendChild(item);
});
};
});
};
// Bootstrap on page load
if (document.readyState === "loading")
document.addEventListener("DOMContentLoaded", window.XamxamInitFileUploads);
else window.XamxamInitFileUploads();