Commit Graph
66 Commits
Author SHA1 Message Date
Pontoporeia 08a9b7309f fix: locked_year cleared on edit — populate edit dialog field
The openEditDialog JS function didn't populate the locked_year input
in the edit dialog, and the PHP template didn't pass locked_year as an
argument. Any edit to a link (even just changing the name) would clear
the locked academic year to NULL.

- Pass $linkLockedYear as 5th argument to openEditDialog in the template
- Accept and populate edit-locked-year input in the JS handler
2026-07-10 11:56:27 +02:00
Pontoporeia 22a49f7cb6 fix: unify CSV import/export columns, fix import JS error, fix createThesis VALUES
- Fix createThesis SQL: extra ? placeholder in VALUES (27 values for 26 columns)
- Add createThesis integration tests to catch column/value mismatches
- Add CSV_COLUMNS as single source of truth in ExportController, deriving
  csvHeaders() and positional fallback from it
- Add missing columns to export query + CSV: duration_pages, duration_minutes,
  has_annexes, license_custom, contact_visible, objet
- Add missing columns to import INSERT: license_id, license_custom, cc2r,
  exemplaire_baiu, exemplaire_erg, objet, contact_visible, duration_pages,
  duration_minutes, has_annexes
- Resolve license name → license_id during import
- Fix XamxamInitFilePonds: add file-upload-filepond.js to admin-entry.js
  so FilePond initialization code is available on the admin list page
- Add FilePond vendor CSS to admin.min.css bundle (import dialog styling)
- Generate .admin-file-hint from csvHeaders() instead of hardcoded stale list
- Use positional fallback from CSV_COLUMNS for import cell parsing
2026-07-10 11:56:27 +02:00
Pontoporeia 20873f94af pdf-viewer: various visual and usability changes
- fix page nav buttons, smaller default pages, violet bg

  - Build toolbar after renderAllPages so it queries existing canvases;
    query canvases fresh in the scroll handler so page tracking works
    after re-render (zoom in/out).
  - Default data-pdf-scale 0.85 (JS fallback 0.8) so pages are a bit
    smaller by default.
  - Add dark transparent violet background (accent-secondary 22%) to
    .pdf-expanded, behind the pages.

  - expand to fill column top-to-bottom via CSS flex

    Use a flex chain (.tfe-files flex:1, .tfe-file-item:has(.pdf-expanded)
    flex:1) so the expanded PDF wrapper fills the right column from under
    the header to the bottom of the viewport, instead of viewport-based
    clamp math that didn't account for the header height.

  - fill right column, center pages, freeze column on expand

  The expanded viewer now stays inside the right column instead of
  growing the page: the column switches to overflow:hidden while the
  PDF panel scrolls internally. Pages are centered horizontally via
  flexbox align-items: center.

  - fix toolbar not full-width, hide sibling file items

  The toolbar was constrained by the parent's align-items:center; fixed
  with align-self:stretch. Hiding sibling .tfe-file-item elements when
  a PDF is expanded prevents them from rendering above the overlay.

  - disable overscroll on expanded view

  - use overscroll-behavior-y on container, none on toolbar

  - disable body overscroll via .pdf-viewer-open class

  - mobile full-viewport, iframe matches pdf height

  - mobile overlay above everything via position:fixed

  - opaque dark-violet bg on mobile overlay

  - tfe: add 'Open in new tab' link above website iframes

  - trim column padding when expanded for more vertical space

  - 5% zoom increments, subtle padding on expanded column

  - prevent horizontal overflow/overscroll
2026-07-08 22:41:52 +02:00
Pontoporeia 82d8eff512 Fix lint: use IterableCallbackReturn — wrap forEach body in braces 2026-07-08 15:14:20 +02:00
Pontoporeia 033ea90684 Fix lint warnings: arrow functions in admin-acces.js, duplicate gap in admin.css, biome formatting 2026-07-08 13:50:03 +02:00
Pontoporeia 402799a412 Fix remaining JS functions missing from window global scope 2026-07-08 13:50:03 +02:00
Pontoporeia 83287cdcd8 Expose tag/langue/motscles JS functions on window to survive ESM tree-shaking 2026-07-08 13:50:03 +02:00
Pontoporeia 10df92b643 fix: load autosave-handler.js on about_page edit view, persist contact group deletion
Two fixes:

1. about_page edit was missing autosave-handler.js: the first if block
   (editType === 'page' || 'about_page') overrode $extraJs with only
   overtype.min.js, making the elseif that added autosave-handler.js
   unreachable for about_page. Added autosave-handler.js to the first
   block, removed dead 'about_page' from the elseif.

2. Deleting a contact group (Contacts 3/4/5) only removed the DOM
   element but never triggered htmx autosave. Dispatched a 'change'
   event on the form after removal+reindex so the hx-trigger fires.

Also expanded autosave-handler.js URL filter to accept apropos.php
so the status indicator (Enregistrement/Enregistré) works for contacts saves.
2026-07-05 14:14:13 +02:00
Pontoporeia 3c845f9d40 acces.php: remove Mot de passe column, add key icon copy button, reorder actions, switch URL icon to link-simple; fix dialog functions not on window; fix archive: move form into dialog (native submit); add caret icon to archived links details 2026-07-05 12:05:53 +02:00
Pontoporeia 3e93150c76 justfile: standardise test recipes to lint-php/lint-css/lint-js/test + add fix recipe
- Removed ambiguous aliases: phpstan, cs-check, syntax
- Split lint-biome into lint-css and lint-js with correct paths
- Added lint meta-recipe and fix recipe (biome --unsafe + php-cs-fixer)
- Fixed FormBootstrap dead null check, CSS shorthand override bug
- Updated phpstan baseline, suppressed noDescendingSpecificity/noInnerDeclarations
- Applied ~74 biome auto-fixes across CSS/JS
2026-07-05 11:07:41 +02:00
Pontoporeia a1f32acaa1 cleanup: sélection multiple + page dédiée (/admin/cleanup.php)
- cleanup-tmp.php: accepte les arrays filepond_dirs[] et trash_files[] pour suppression en lot
- cleanup-stats-fragment.php: ajout checkboxes + barre d'actions groupées + formulaire bulk HTMX
- admin-cleanup-bulk.js: module JS pour toggleAll, updateBulk, bulkDelete
- Nouvelle page /admin/cleanup.php remplace la modale (tmp-cleanup.php supprimé)
- Bouton Nettoyer dans index.php devient un lien vers la page dédiée
2026-07-03 17:06:23 +02:00
Pontoporeia 880d169e72 search: pagination and scroll, add range counter, mobile version 2026-07-03 16:53:16 +02:00
Pontoporeia 4fa57d592a refactor: combined duration (pages + minutes), has_annexes checkbox, remove Mo
- Remove Mo option from duration, keep only pages and minutes
- Redesign duration fieldset: separate Pages input + Durée h:m inputs, both can be set together
- Fix minutes input visibility: wider inputs (6ch), proper CSS layout
- Add has_annexes checkbox to fichiers fragment + DB column + controllers
- Display duration on admin backoffice recap page
- Display duration on public partage recap page
- Update public TFE page for new combined duration format
- Migration 041: add duration_pages, duration_minutes, has_annexes columns; migrate data; recreate views
2026-07-03 15:58:10 +02:00
Pontoporeia eb706214ce feat: scroll-position memory on repertoire HTMX swaps + swap transition polish
- Add repertoire-scroll-restore.js: snapshots scrollTop of each column <ul>
  before htmx:beforeSwap, restores after htmx:afterSwap (keyed by data-col)
- Add subtle opacity transition on #repertoire-index during htmx-swapping
- Tighten rep-indicator opacity transition to 0.1s for snappier feedback
- Import new module in public-entry.js
2026-06-24 14:45:55 +02:00
Pontoporeia 6ecd3d4540 Fix biome lint errors: remove duplicate CSS properties, apply safe auto-fixes
CSS:
- Remove duplicate 'background' fallbacks in base.css, header.css, search.css
  (solid color declared before gradient — gradient always wins)
- Remove duplicate 'padding' in admin.css .admin-import-log

JS (biome --write safe fixes applied):
- function() → arrow functions in all IIFEs and callbacks
- forEach/callback → arrow functions
- evaluePtrn → parseInt(x, 10) in admin-contacts-form.js
- Cleaned label text in build.mjs lint step

Remaining warnings are intentional: !important overrides, descending
specificity (admin.css cascade), noUnusedVariables (functions exported
to window/onclick), useTemplate style preference.
2026-06-24 13:57:00 +02:00
Pontoporeia 82d3dcb084 Fix repertoire column scrolling + admin TOC duplication
- repertoire.css: add min-height: 0 to column <ul> scroll containers so
  grid 1fr row shrinks below content and overflow-y: auto activates
- admin-toc.js: add __adminTocBuilt guard + nav.children check to prevent
  double population when loaded both via admin.min.js and direct <script>
- admin-toc.php: remove duplicate <script src="admin-toc.js"> tag —
  JS is already bundled in admin.min.js
2026-06-24 13:18:19 +02:00
Pontoporeia 20fe4b6c8c Add biome + rolldown + lightningcss build pipeline for JS/CSS bundling & minification
- package.json with biome, rolldown, lightningcss devDependencies  
- biome.json: add CSS formatter support
- scripts/build-css.mjs: lightningcss resolves @import chain, bundles/minifies CSS  
- scripts/build-js.mjs: rolldown per-entry JS bundling (no code splitting)
- scripts/build.mjs: orchestrator for both CSS + JS
- scripts/check-build.mjs: staleness checker for CI/deploy guard
- justfile: add build, build-css, build-js, build-install, build-check recipes
- justfile: deploy recipe now runs build before deploy-code
- head.php + form-page.php: use dist/base.min.css instead of style.css
- All controllers + FormBootstrap: reference dist/*.min.{css,js}
- admin footer: load admin.min.js for all admin pages
- repertoire: use public.min.js instead of individual app JS files
- Fix stray '}' syntax error in admin.css line 305
- .gitignore: add app/public/assets/dist/
2026-06-24 13:09:50 +02:00
Pontoporeia e74f9210c5 #gzip #extract-inline-js enable gzip in nginx + move ~730 lines of inline JS to 15 external files 2026-06-24 12:56:15 +02:00
Pontoporeia 03c9c3566f Add SQLite indexes for contenus page language/tag queries + WIP: Peertube orphans, dialogs, contact decoupling, context note, finality types 2026-06-21 16:36:34 +02:00
Pontoporeia 19bf9f101a Refactor apropos/charte/licence pages: shared layout, TOC anchors, and UI polish
Unify the three public pages (à propos, charte, licence) onto a single
grid layout (.page-content) with sticky TOC sidebar, replacing the old
separate  /  /  markup.

- Merge about.php, charte.php, licence.php templates into shared
  .page-content / .content-section structure
- Add CommonMark HeadingPermalinkExtension for stable heading anchors
- Use SlugNormalizer for TOC links so they match rendered heading IDs
- Standardize link styling across content blocks: bold black, accent on
  hover (consistent with global link style)
- Fix code block wrapping: use pre-wrap instead of pre, constrain grid
  columns with min-width:0, auto scrollbar
- Fix apropos page grid placement: force content-section into column 2
  so contacts and credits stay in the content area, not the sidebar

Also includes accumulated WIP changes:
- Header gradient: hardcoded purple-to-green (replaces CSS variables)
- Search placeholder font
- Duration field: replace minutes/sec/heures with h:m:s time inputs
- TFE file optional for formats 1,4,6 with client-side JS toggle
- Licence form: em-dash to hyphen, details/summary classes
- Pill search: block Enter key form submission when no results
- Draft autosave: remove CSRF rotation (broke concurrent FilePond uploads)
- Language pill: clear hints for excluded main languages
- Search results: gradient placeholder cards for items without covers
- TFE display: format durée values as XhYm instead of decimal
2026-06-19 19:40:05 +02:00
Pontoporeia a5db81a73d fix: change adminOld return type from string to string|array
The closure returned arrays when formData values were arrays (e.g.
jury_promoteur), but the PHP return type annotation was :string.
PHP 8.x enforces this strictly, causing a fatal TypeError in
jury-fieldset.php on add mode.
2026-06-15 16:17:29 +02:00
Pontoporeia d588ae004d Reintroduce TFE duration metadata: DB columns, form fields, controllers, views, and migration
Add 'unsafe-eval' to CSP script-src directives (htmx requires Function())
2026-06-15 15:56:52 +02:00
Pontoporeia cbd369bc72 Split form.css into form-base.css and form-admin.css, drop dead upload-progress code
Also introduces $extraCssAdmin support in head.php for admin-only
stylesheets (form-admin.css, filepond CSS, system.css). Admin pages
now use $extraCssAdmin for admin-only assets and $extraCss for
shared stylesheets like form-base.css.
2026-06-11 11:28:58 +02:00
Pontoporeia 99125cc8e3 Add autosave draft system for partage form with HTMX-based session persistence
- New fragment endpoint POST/GET /partage/fragments/draft.php:
  saves all form fields to PHP session, excludes file/csrf/slug fields
  GET returns JSON for JS hydration on page load
  rotates both global CSRF and share CSRF tokens in sync

- form.php accepts optional $formExtraAttrs and $showAutosaveStatus:
  allows injecting HTMX attributes and 'Brouillon enregistré' indicator

- renderShareLinkForm adds hx-post with change/input debounce trigger,
  loads autosave-handler.js, hydrate fields from draft on page load

- Draft cleared on successful form submission in handleShareLinkSubmission

- autosave-handler.js now also updates share_link_token hidden input
  when rotating CSRF token (partage form uses both csrf_token and share_link_token)

- Added .autosave-status CSS to form.css (was admin.css-only)

- Updated fragment routing to accept GET requests (needed for draft hydration)
2026-06-11 11:04:49 +02:00
Pontoporeia 4b37a05be3 Guard no-JS file uploads: disabled filepond_mode by default, server-side fallback
The partage/admin form had a hardcoded filepond_mode=1 hidden input,
so without JavaScript the server always entered the FilePond async
path — which found no hex IDs and silently dropped all files.

Three-layer fix:
1. HTML: filepond_mode input starts disabled with value=0; JS enables
   it and sets value=1 on DOMContentLoaded (and after HTMX swaps).
   Disabled inputs aren't submitted → server gets no filepond_mode
   → naturally falls to legacy  path.
2. JS: enableFilepondMode() called on page load and hx:afterSwap so
   FilePond-enhanced forms always send filepond_mode=1.
3. Server (defense-in-depth): ThesisFileHandler::hasFilePondQueueData()
   scans POST['queue_file'] for 32-char hex IDs; ThesisCreateController
   and ThesisEditController use it alongside filepond_mode, so even if
   the flag somehow arrives without async upload IDs, the  path
   takes over.
2026-06-11 10:32:50 +02:00
Pontoporeia fb752f5ba2 cleanup: remove _write guard — FilePond external API doesn't expose _write
ro=['fire','_read','_write'] is an exclusion list in Ee(), not an inclusion
list. The external pond object has none of these. The only safe interception
point is inside the closure (vendor patch), but the root-cause fix
(fileValidateSizeFilter .filename → .name) already prevents the crash.
2026-06-10 00:18:49 +02:00
Pontoporeia 2829d13a16 filepond: fix crash 'can't access property main, n.status is undefined'
Fixes three root causes of FilePond errors on TFE upload forms:

1. server.process.onerror accessed .status on a string (XHR response
   text body) — now extracts the body safely.

2. server.load was a bare URL string with no error handling — converted
   to object with onload/onerror to prevent FilePond internal _write
   crash when load.php returns HTTP errors.

3. destroyFilePondsIn now aborts in-flight processing before pond.destroy()
   to prevent stale XHR callbacks firing on a torn-down FilePond instance.

Server-side: FilepondHandler now emits Content-Type: text/plain on all
responses (PHP defaults to text/html on die(), confusing FilePond's
response parser).
2026-06-10 00:18:49 +02:00
Pontoporeia 38ef550397 feat: render actual elements in markdown cheatsheet instead of labels
Replace text labels (h1, bold, italic) with rendered HTML in the Rendu column:
headings, strong, em, del, code, links, blockquote, lists, hr, sup, small
2026-06-10 00:18:49 +02:00
Pontoporeia 1490c99268 Fix FilePond: maxFileSize as bytes + temp files survive page reload
1. maxFileSize bug: FileValidateSize plugin overrides core's maxFileSize
   setter. Core uses toBytes('1GB') = 1073741824, but plugin registers
   maxFileSize as [null, Type.INT] which calls toInt('1GB') = 1.
   Fix: all maxFileSize and perExtensionMaxSize values as raw bytes.
   Also fix option name: fileValidateSizeFilterItem → fileValidateSizeFilter.

2. Temp file persistence: files uploaded via FilePond went to
   tmp/filepond/ and vanished from the UI on page reload because
   data-existing-files only included DB-persisted files.
   Fix: session-track temp file_ids in handleProcess, inject via
   getSessionTempFiles() into data-existing-files, teach handleLoad
   to stream temp files from disk, and route JS remove → revert for hex IDs.
2026-06-10 00:18:49 +02:00
Pontoporeia c4a550f9d1 Rework contenus-edit: auto-save, OverType toolbar, dynamic sidebar links
- Auto-save: new autosave.js with 1.5s debounce, watches all forms with
  data-autosave, POSTs to form action with Accept: application/json, shows
  saving/saved/error status indicator
- All action handlers (page.php, apropos.php, form-help.php) now detect
  JSON Accept header and return {success, csrf_token} or {error} responses
- OverType toolbar enabled (toolbar:true) on all three markdown editors
  (page, about_page, form_help)
- Sidebar links: replaced fixed erg_site_url / source_code_url rows with
  dynamic sidebar_links array of {label, url} objects. Add/remove via JS.
  Fallback migration reads legacy keys if sidebar_links is empty.
- Updated AboutController and about.php template to render dynamic links
- Updated apropos.css: unified .apropos-toc-link replacing .apropos-toc-erg
  and .apropos-toc-source
- New CSS: autosave-status states, sidebar-link-row layout
- Removed all Enregistrer + Annuler buttons — auto-save and h1 back-arrow
  make them redundant
2026-06-10 00:18:40 +02:00
Pontoporeia 3d524226a1 formulaire: correctifs identifiant/année, contact, fichiers optionnels
- Identifiant: mise à jour automatique quand l'année change en back-office (updateThesis + ThesisEditController)
- Contact: hint enrichi (1 seul contact, formatage Instagram/Mastodon)
- Fichiers: TFE rendu optionnel pour Site web/Performance/Installation (note d'intention reste obligatoire)
2026-06-10 00:17:00 +02:00
Pontoporeia df70fba5d4 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
2026-06-09 13:12:22 +02:00
Pontoporeia 2bb520bb8c Fix: anchor vendor/ gitignore to root so app/public/assets/js/vendor/ is tracked (htmx, OverType, FilePond) 2026-06-08 10:12:39 +02:00
Pontoporeia 2e75a3b35c Fix beforeunload dialog appearing on edit.php when no changes made 2026-05-19 23:59:07 +02:00
Pontoporeia 7c30d1c55d Fix relink: close modal + HTMX refresh for immediate pool update
- After relink, always close the modal (even if FilePond input not found,
  e.g. page refreshed by live-reload during the fetch).
- After closing, re-fetch #format-fichiers-block via HTMX from
  /admin/fragments/fichiers.php?_thesis_id=N which loads thesis files
  from DB and re-renders the fragment with pre-populated FilePond pools.
  The afterSwap handler auto-reinitializes FilePond instances.
- Updated admin/fragments/fichiers.php to accept _thesis_id, load
  existing files from DB, build per-queue-type JSON, and render in
  edit mode.
2026-05-19 01:32:34 +02:00
Pontoporeia b77bc486e5 Fix relink: FilePond addFile API, yellow border, limbo type + await
- Fix addFile argument format: FilePond.addFile() takes (source, options)
  as two separate arguments, not a single {source, options} object.
- Change .filepond--file default border from accent-yellow to accent-green.
  Existing files loaded in edit mode have type 'local' and never reach
  processing-complete state, so they got the yellow border.
- Change relinked file add from type 'local' to 'limbo'. Limbo items
  go through DID_COMPLETE_ITEM_PROCESSING which triggers onprocessfile
  (ensures syncOrderInput runs with serverId available) and renders
  the green checkmark visual.
- Await addFile Promise and close modal in .then() instead of
  immediately, ensuring the item is created before cleanup.
- Remove duplicate modal.close() after the addFile block.
2026-05-19 01:13:17 +02:00
Pontoporeia 27e6abc7e4 feat: file browser + relink for orphaned files + htmx fix + header cleanup + fix relinked FilePond integration + resolve acces.php conflict markers 2026-05-19 00:08:06 +02:00
Pontoporeia 79eddf5d5a feat: fix file deletion on save + trash policy + documents/ prefix + relink browser
1. note_intention: Delete old file only when a genuinely new upload arrives
   (32-char hex file_id), not when the FilePond pool preserves an existing
   file by sending its DB integer ID.  Previously the DB integer ID
   triggered $hasNewNote=true, which deleted the existing note_intention
   from disk+DB, then handleFilePondSingleFile couldn't re-process it
   because the regex requires a hex pattern.  Same fix applied to cover.

2. All file deletions now use deleteThesisFileToTrash() which renames
   files to tmp/_trash/ instead of unlinking.  The trash preserves
   original filenames prefixed with DB id for traceability.  Skips
   website URLs and PeerTube refs (no disk file).

3. Storage prefix changed from theses/ to documents/ to reflect that
   the folder holds all document types (determined by file_type in DB).
   MediaController visibility gate supports both prefixes for backward
   compat with existing files.

4. File browser + relink feature for orphaned files:
   - /admin/fragments/file-browser.php — HTMX tree browser for
     storage/documents/ and storage/theses/
   - /admin/actions/filepond/relink.php — POST endpoint that inserts
     a thesis_files row pointing to existing on-disk file
   - Per-pool "📂 Relier" buttons (edit mode only)
   - JS: XamxamOpenFileBrowser / XamxamRelinkFile with FilePond integration
   - CSS: .relink-modal dialog + .file-browser tree styles
2026-05-19 00:08:06 +02:00
Pontoporeia 6f7a02244f maintenance: allow /partage through gate, fix fragment routing, add visibility table in admin
Extract shared filepond logic into src/FilepondHandler.php class.
Admin filepond endpoints delegate to the handler after AdminAuth check.
New partage filepond endpoints at /partage/actions/filepond/ verify
share_active session flag + CSRF token, no admin auth required.

JS reads filepond-base meta tag to determine endpoint path:
- Admin pages: /admin/actions/filepond (via head.php isAdmin check)
- Partage form: /partage/actions/filepond (explicit meta)

partage/index.php sets share_active = true on form render, cleans up on
successful submit. Partage process endpoint rate-limited to 30/5min per
session. No nginx changes needed — /partage/ location already handles
PHP without auth_basic.
2026-05-19 00:08:06 +02:00
Pontoporeia 9152b120e8 feat: mandatory auto-generated passwords for share links + admin password copy/regeneration + password gate rate limiting 2026-05-19 00:08:06 +02:00
Pontoporeia 6e7c0c00e3 refactor: merge video/audio FilePond pools into TFE input
- Remove separate video/audio/peertube_video/peertube_audio pools from UI
- TFE pool now accepts all file types including video/audio
- When PeerTube is enabled, video/audio dropped into TFE pool auto-upload
  to PeerTube (process.php detects MIME and uploads immediately)
- PeerTube return IDs now encode type: peertube:video:UUID or peertube:audio:UUID
- load.php returns placeholder SVG for PeerTube files so they appear in FilePond
- Edit mode: all existing files (including PeerTube) shown in TFE FilePond pool
- Remove legacy  video/audio/peertube_* handling from both controllers
- Remove unused vide/audio/peertube_* entries from JS QUEUE_CONFIG
2026-05-19 00:08:06 +02:00
Pontoporeia 2e9ebfc684 filepond: implement async server-ID upload architecture with nested queue support + PeerTube integration
Replace `storeAsFile:true` with a full async FilePond round-trip pipeline using opaque server-side file IDs.

* Added 4 new PHP endpoints under `/admin/actions/filepond/`:

  * `process.php` — upload/process single file and return opaque `file_id`
  * `revert.php` — delete pending tmp uploads before form submit
  * `load.php` — stream existing files by DB ID for FilePond preload
  * `remove.php` — soft-delete `thesis_files` rows
* `process.php` improvements:

  * accept arbitrary FilePond field names instead of hardcoded `file`
  * support PHP-nested multi-file queue inputs (`queue_file[tfe][]`)
  * explicit unwrapping of nested `$_FILES` structures
  * add `audio/mp3` to audio + `peertube_audio` MIME whitelists
  * immediate upload of `peertube_*` files to PeerTube, returning `peertube:{uuid}` IDs
  * extensive `error_log()` instrumentation for request, CSRF, MIME, upload, and save stages
* `revert.php` now accepts `peertube:` IDs without local cleanup
* `ThesisFileHandler`:

  * add `handleFilePondQueueFiles()` + `handleFilePondSingleFile()`
  * process async uploads from `storage/tmp/filepond/` via opaque `file_id`
  * inline handling of `peertube:{uuid}` IDs with direct `thesis_files` insertion
  * remove obsolete deferred PeerTube queue-processing flow
* `ThesisCreateController` + `ThesisEditController`:

  * gate async path behind `filepond_mode=1`
  * preserve legacy multipart flow as fallback
* `file-upload-filepond.js`:

  * remove `storeAsFile:true`
  * add `buildServerConfig()` for async endpoint wiring
  * fix `syncOrderInput()` to use `serverId`
  * add `onprocessfile` hook
  * add `fileValidateSizeFilterItem` for per-extension size caps
  * preload existing uploads via `data-existing-files` + `server.load`
  * replace static `INPUT_ID_TO_TYPE` map with `data-queue-type`
  * add extensive `console.log()` debugging across upload pipeline stages
* `upload-progress.js`:

  * block form submission while uploads are pending
  * update `collectFileNames()` to read processed FilePond items
* Templates/layout:

  * add `data-queue-type`
  * add `data-existing-files`
  * add global CSRF meta tag outside admin-only context
  * add `filepond_mode` hidden input
  * add CSRF token/meta support for partage pages
  * move website URL field below file upload block
* `.gitignore`: exclude `storage/tmp/` from version control
2026-05-19 00:08:06 +02:00
Pontoporeia b56d073210 refactor: extract inline JS into app/ modules, remove dead overtype-webcomponent
- Remove overtype-webcomponent.min.js (zero references)
- Extract copyLogContent + fallbackCopy + HTMX tab-updater → app/admin-logs.js
  (removes duplicate from both system.php and parametres.php)
- Extract copyUrl → app/clipboard.js (shared by acces.php)
- Extract tag/language pill-search logic → app/pill-search.js
  Generalized with data-pill-search attributes, auto-inits via
  DOMContentLoaded + htmx:afterSwap
- Extract access-request form handler → app/access-request.js
  (was inline in templates/public/tfe.php)

Files created: admin-logs.js, clipboard.js, pill-search.js, access-request.js
Files modified: 9 templates/controllers to drop inline scripts and
  reference external JS files
2026-05-19 00:08:06 +02:00
Pontoporeia c3f6e8a033 fix: upload progress bar not visible — collectFileNames checks FilePond instances; remove admin auth from progress poll endpoint 2026-05-19 00:08:06 +02:00
Pontoporeia 927ee2fe2a feat: upload progress bar — fieldset layout, accent colors, file name display, completion animation, 800ms redirect delay; decorelate formats from fichiers; server-side poll via token; bump PeerTube embed audio player 2026-05-19 00:08:06 +02:00
Pontoporeia cdec3e96a6 fix PeerTube upload: final working solution — simple multipart POST with CURLFile; iterated through Google-resumable PATCH protocol debugging (HTTP version negotiation, chunk body encoding, off-by-one fixes) before settling on simpler POST approach 2026-05-19 00:08:06 +02:00
Pontoporeia 83a5a508ea feat: PeerTube integration — alternate audio/video labels, FilePond pools, shared SMTP credentials, channel by name, test button, resumable upload, embed improvements, fix alt labels/curl_close/deprecation 2026-05-19 00:08:06 +02:00
Pontoporeia 8db7b6e9eb feat: FilePond production hardening — extension-based validation, server-side size limits (2GB), annexe validation, drop accept attributes, FilePond file styling 2026-05-19 00:08:05 +02:00
Pontoporeia 7b5f3efe40 feat: add FilePond pools for couverture, note_intention, video, audio; refactor queue config 2026-05-19 00:08:05 +02:00
Pontoporeia ecb559a18a refactor: decouple format extras from main fichiers block, scope FilePond destroy to individual slots, fix FilePond integration for decoupled extras 2026-05-19 00:08:05 +02:00