Replace HTMX+PHP file upload queues with client-side JS

Drops the session-backed HTMX incremental upload system in favour of a
single JS module that manages `File` objects client-side and injects
them into `FormData` on submit.

Key changes:

* `file-upload-queue.js`: client-side queues with validation, reorder
  (SortableJS), removal, dirty-state tracking, and fetch-based submit
  with manual redirect handling
* `fichiers-fragment.php`: empty queue containers for JS-managed queues;
  HTMX format switching still works with queue rehydration after swap;
  annexe uploads now support multiple files
* Form UI cleanup: moved existing files and cover preview into the
  `Fichiers` fieldset (edit mode); removed redundant queue labels while
  keeping labels for single-file inputs (`couverture`,
  `note d'intention`); added delete buttons for existing files
* `ThesisFileHandler.php`: added
  `handleTfeQueueFiles()`/`handleAnnexeQueueFiles()` reading from
  `$_FILES['queue_file']`; introduced `extractFilesSubArray()` for
  nested upload arrays; removed session-based queue handling
* `ThesisCreateController.php` &
  `ThesisEditController.php`: switched to extracted
  `['queue_file']` uploads
* `beforeunload-guard.js`: now also watches
  `window.__xamxamDirty`
* Deleted obsolete PHP upload/remove/reorder queue endpoints for
  `partage` and `admin`
* Cleaned up route dispatch in `partage/index.php`
* Misc form and styling updates in templates/CSS
* Added `docs/cms-migration-plan.html`
This commit is contained in:
Pontoporeia
2026-05-10 17:16:25 +02:00
parent 98ed83fac2
commit 13d26ded66
20 changed files with 2063 additions and 753 deletions

View File

@@ -338,109 +338,7 @@ $checkedFormatsForSiteWeb = $checkedFormatsForSiteWeb ?? [];
unset($_savedPost);
?>
<!-- Edit-only: existing files management -->
<div id="edit-existing-files-block">
<!-- Existing thesis files — with labels -->
<?php $thesisFilesList = array_values(
array_filter(
$currentFiles,
fn($f) => $f["file_type"] !== "cover",
),
); ?>
<?php if (!empty($thesisFilesList)): ?>
<div class="admin-form-group">
<label>Fichiers du TFE existants :</label>
<ul id="existing-files-sortable" class="admin-file-list">
<?php foreach ($thesisFilesList as $f):
$fExt = strtolower(
pathinfo($f["file_path"] ?? "", PATHINFO_EXTENSION),
);
$fType = $f["file_type"] ?? "other";
$fIcon = match (true) {
$fType === "main" || $fExt === "pdf" => "📄",
in_array($fExt, [
"jpg",
"jpeg",
"png",
"gif",
"webp",
])
=> "🖼️",
$fType === "video" ||
in_array($fExt, ["mp4", "webm", "mov", "ogv"])
=> "🎬",
$fType === "audio" ||
in_array($fExt, [
"mp3",
"ogg",
"wav",
"flac",
"aac",
"m4a",
])
=> "🔊",
$fType === "caption" || $fExt === "vtt" => "💬",
$fType === "website" => "🌐",
default => "📎",
};
$isExternalUrl =
str_starts_with($f["file_path"] ?? "", "http://") ||
str_starts_with($f["file_path"] ?? "", "https://");
$fLinkHref = $isExternalUrl
? htmlspecialchars($f["file_path"])
: "/media?path=" . urlencode($f["file_path"]);
?>
<li class="admin-file-list-item" data-file-id="<?= (int) $f[
"id"
] ?>">
<input type="hidden" name="file_sort_order[]" value="<?= (int) $f[
"id"
] ?>">
<span class="admin-file-icon-col"><?= $fIcon ?></span>
<span class="admin-file-info">
<a href="<?= $fLinkHref ?>" target="_blank" rel="noopener" class="admin-file-name">
<?= htmlspecialchars(
$f["file_name"] ??
basename($f["file_path"]),
) ?>
</a>
<span class="admin-file-meta-row">
<span class="admin-file-type-badge"><?= htmlspecialchars(
$fType,
) ?></span>
<?php if (
!empty($f["file_size"]) &&
$f["file_size"] > 0
): ?>
<span class="admin-file-size"><?= number_format(
$f["file_size"] / 1024 / 1024,
2,
) ?> MB</span>
<?php endif; ?>
</span>
<input type="text" name="file_label[<?= (int) $f[
"id"
] ?>]"
value="<?= htmlspecialchars(
$f["display_label"] ?? "",
) ?>"
placeholder="Légende / description (optionnel)"
class="admin-file-label-input">
</span>
<label class="admin-checkbox-label admin-file-delete">
<input type="checkbox" name="delete_files[]" value="<?= (int) $f[
"id"
] ?>"> Supprimer
</label>
</li>
<?php
endforeach; ?>
</ul>
</div>
<?php endif; ?>
</div><!-- #edit-existing-files-block -->
<?php endif; ?>
<!-- ═══════════════════ Métadonnées complémentaires ═══════════════════