Track each uploading file's drop target folder via a Map.
When a folder is deleted, selectively cancel only the
uploads that were dropped into that folder, leaving other
uploads unaffected.
Add overflow-x: auto on the search modal inputs container to prevent
layout breakage when filters exceed available width, and upgrade
@gouvfr-lasuite/ui-kit from 0.20.0 to 0.20.1.
The trash hard delete confirmation modal always displayed "2 items"
regardless of how many items were selected, because it received a
boolean `multiple` prop and hardcoded `count: 2` for the i18n
interpolation. Replace the boolean with the real selection length so
the plural message reflects the actual count.
Test that My Files shows the more menu with create
folder and import options on mobile viewport.
Test that the more menu button is visible inside
a folder on mobile viewport.
The more_vert button was only shown inside folders
on mobile. This adds a dropdown with create folder
and import options on the My Files default route.
Also adds includeCreate option to useCreateMenuItems
to allow excluding document creation items.
Use String.localeCompare in three test sort() calls to satisfy
the reliability rule S2871, and drop the redundant Event branch
of the Event | unknown parameter type in customGetFilesFromEvent
(S6571).
Cover the custom drop traversal helpers: empty-folder marker
creation, batched readEntries() loop, recursive entry walking
for files, nested non-empty folders, and empty directories, plus
the customGetFilesFromEvent entry point for drop events and its
delegation to file-selector for non-drag inputs.
React-dropzone's default traversal silently drops empty directories
because webkitGetAsEntry()'s readEntries() yields no entry for them.
Add a custom getFilesFromEvent that walks the drop tree ourselves
and emits a zero-byte marker file for every empty folder. The marker
carries an isEmptyFolder flag and a path so useUpload can materialize
the folder chain via getFolderByPath, then skip the marker before any
size validation or backend upload.
When a drop contains only empty-folder markers, the file upload toast
is suppressed and a dedicated success toast is shown once the folders
have been created. Input change events (folder/file buttons) are
delegated to file-selector, matching the Google Drive / Proton Drive
limitation around <input webkitdirectory>.
Pillow 12.1.1 is vulnerable to CVE-2026-40192 (FITS GZIP decompression
bomb). easy_thumbnails pulls pillow transitively with no upper bound,
so enforce the floor via a uv constraint rather than a direct
dependency bump.
An item is considered hard deleted in two cases:
- hard deletion was forced by the user while sitting in the trashbin
- the item was only soft deleted but the trashbin retention period
has expired
Thus, a hard deleted item still exists in database with an associated
file in S3. What the asynchronous task is doing is another action:
permanently removing the item from database and its associated file
from S3. I propose to rename this action "purge".
We refactor the task to improve its resilience:
- don't recursively generate asynchronous tasks. We are already
outside of a request cycle so we don't need to spawn new
asynchronous tasks.
- purge the subtree from the bottom to the top: leaves first,
root last.
- fail fast if something goes wrong and make sure the task will
continue when we retry it.
- Add per-file status tracking (uploading/done/error/cancelled)
- Show error details inline with tooltips for failed uploads
- Display overall progress percentage during upload
- Add cancel overlay on hover for individual files
- Add confirmation modal when cancelling all uploads
- Handle too-large files as inline errors instead of separate toasts
- Add translations for error messages and cancel modal (en/fr/nl)
Added
- ✨(frontend) add PDF viewer with thumbnail sidebar, zoom and page navigation
- ✨(frontend) integrate PDF viewer into file preview modal
- 📝(doc) add local network setup documentation
- ✨(global) add custom columns feature with configurable grid columns
- 🔒️(frontend) prevent search engine indexing
- ✨(backend) allow ordering items by creator full name
- ✨(frontend) add item duplication with polling and visual feedback
- ⚡(ci) shard e2e tests and cache playwright browsers
- ⬆️(frontend) upgrade cunningham-react and ui-kit to 0.20.0
- ✨(frontend) improve custom columns with sortable config and i18n
Changed
- 🏷️(sdk) update Item interface by adding url_permalink
- 🔧(backend) allow extra CSRF origins via env variable
- 🔧(nginx) serve .mjs files with correct MIME type
Fixed
- 🐛(backend) fix hard delete of files created by other users
- 🐛(backend) handle race condition on concurrent LinkTrace creation
- 🐛(frontend) fix React SVG attributes in AddFolderButton
- 🔧(scalingo) compile translation files at deploy time
- 🐛(frontend) fix trash items not refreshing after hard delete
- 🐛(frontend) show modal when clicking files in trash
- 🐛(frontend) fix toasts appearing above modals
Introduce the 0.16.0 release note highlighting customizable columns,
column sorting, document duplication and the new built-in PDF viewer,
with translations for en, fr and nl.
CodeQL flagged the workflow for running with default GITHUB_TOKEN
permissions. None of the jobs need write scopes, so pin to the
minimum to contain blast radius if a third-party action is
compromised.
Replace the per-shard \`yarn dev\` with a single static build
job whose output is shared as an artifact and served by stock
nginx using the production vhost. Cuts e2e startup cost and
exercises the same bundle we ship.
The static export router only matches valid uuid patterns, so
"not_a_uuid" never reaches the preview page. Use a well-formed
but non-existent uuid to actually exercise the 404 path.
NODE_ENV no longer reliably signals a test/dev runtime once the
e2e build is produced as a production static export. Switch to
NEXT_PUBLIC_POSTHOG_TEST_MODE so we can opt in explicitly when
running under Playwright.
Key the Playwright browser cache by the installed @playwright/test
version instead of yarn.lock so cache hits actually match the binaries
Playwright expects, avoiding redundant browser downloads on every CI
run. On cache hit we still install system deps to keep headless runs
working.
Added interception for list endpoints in the duplicate item e2e tests to
override the state of duplicated items, ensuring accurate testing of
upload states during the duplication process.
Add a sortable flag to ViewConfig to conditionally
hide sort buttons per view (disabled for Recent).
Propagate viewConfig through AppExplorer context to
all column headers.
Also prevent selecting the same column type in both
custom column slots by passing otherColumnType and
disabling already-selected options in the dropdown.
Add i18n support for file size units (B, KB, MB, etc.)
so they display correctly per locale (e.g. ko, Mo, Go
in French). Update formatSize to accept a translation
function and update all callers accordingly.
Upgrade cunningham-react to 4.3.0 and ui-kit to 0.20.0.
Theme names are renamed to match the new naming
convention (anct→anct-light, dark→dsfr-dark,
default→dsfr-light). Replace custom deepMerge with
the deepmerge library.
Move the selection border from the outer button to the inner
thumbnail canvas so it wraps the page tightly. Highlight
the page number on the active thumbnail for better visual
feedback.
Toasts were displayed on top of modals and file preview
overlays because toastify default z-index was higher than
our modal z-index (1000). Setting it to 999 ensures proper
stacking order.
Clicking a deleted file in the trash was trying to open a preview,
causing a 403 redirect. We now intercept file clicks in trash the
same way we do for folders: by showing an informative modal asking
the user to restore the item first. The modal message now also
distinguishes between files and folders for clarity.
Closes#601
Scope the ready-state assertions to the copied row and extend the
timeout so slower CI browsers have time to cover several 3s poll
cycles, avoiding races with unrelated re-renders.
E2e tests take 20-23min per browser because they run sequentially
on a single runner with no browser caching. Shard tests across 3
parallel runners per browser and cache Playwright browser binaries
to reduce wall-clock time to ~7min per browser.
When deleting the current folder, the onSuccess callback was
invalidating the children query for the deleted item. This
triggered a refetch that returned 403, causing a hard redirect
to the error page. We now remove these queries from the cache
instead of invalidating them.