feat: convert all file inputs to FilePond for standardized uploading

- Add csv_import queue type (storeAsFile, no async upload) for CSV import dialog
- Convert file-field.php partial to FilePond with field-name→queue-type mapping
- Conditionally skip server config for storeAsFile queues in buildFilePondOptions
- Skip FilePond init for inputs inside closed <dialog> elements
- Trigger FilePond init when import dialog opens
- Load FilePond CSS/JS assets on admin index page
This commit is contained in:
Pontoporeia
2026-06-08 10:28:39 +02:00
parent fad38f4e0d
commit df70fba5d4
8 changed files with 1089 additions and 41 deletions

View File

@@ -515,6 +515,8 @@ if ($isHtmx) {
include APP_ROOT . '/templates/admin/index-table.php';
}
} else {
$extraCss = ['/assets/css/filepond.min.css', '/assets/css/filepond-plugin-image-preview.min.css'];
$extraJs = ['/assets/js/vendor/filepond.min.js', '/assets/js/vendor/filepond-plugin-file-validate-type.min.js', '/assets/js/vendor/filepond-plugin-file-validate-size.min.js', '/assets/js/vendor/filepond-plugin-image-preview.min.js', '/assets/js/vendor/filepond-plugin-image-exif-orientation.min.js', '/assets/js/app/file-upload-filepond.js'];
require_once APP_ROOT . '/templates/head.php';
include APP_ROOT . '/templates/header.php';
if ($tab === 'trash') {

View File

@@ -99,6 +99,18 @@
labelMaxFileSize: "Taille max: {filesize}",
allowMultiple: false,
},
csv_import: {
acceptedFileTypes: ["text/csv"],
labelFileTypeNotAllowed: "Seulement CSV",
fileValidateTypeLabelExpectedTypes: "CSV",
maxFileSize: "50MB",
labelMaxFileSizeExceeded: "Fichier trop volumineux",
labelMaxFileSize: "Taille max: {filesize}",
allowMultiple: false,
// CSV import stays as storeAsFile (no async upload to process.php),
// so the form submits the file directly.
storeAsFile: true,
},
};
// ── Helpers ───────────────────────────────────────────────────────────
@@ -300,13 +312,11 @@
// Per-type max size overrides (for TFE: PDF=100MB, video/audio=2GB)
var perExtMax = cfg.perExtensionMaxSize || {};
return {
// Base options shared by all queue types
var opts = {
allowMultiple: cfg.allowMultiple,
allowReorder: true,
// ── Async server model (replaces storeAsFile + allowProcess: false) ──
server: buildServerConfig(queueType),
// ── Native FilePond validation ──
acceptedFileTypes: cfg.acceptedFileTypes,
labelFileTypeNotAllowed: cfg.labelFileTypeNotAllowed,
@@ -378,6 +388,16 @@
if (!error) syncOrderInput(queueType, this);
},
};
// storeAsFile queues skip async upload; the file stays in the form
if (cfg.storeAsFile) {
opts.storeAsFile = true;
opts.allowProcess = false;
} else {
opts.server = buildServerConfig(queueType);
}
return opts;
}
// ── Public API ────────────────────────────────────────────────────────
@@ -391,6 +411,11 @@
// Canonical duplicate check: FilePond.find() is the authoritative source
if (FilePond.find(input)) return;
// Skip inputs inside closed <dialog> elements — FilePond can't render
// when the container has display:none. Initialize when the dialog opens.
var dialog = input.closest("dialog");
if (dialog && !dialog.open) return;
// Queue type: always from data-queue-type attribute
var queueType = input.dataset.queueType || null;
if (!queueType) return;