Commit Graph
1090 Commits
Author SHA1 Message Date
Nathan Vasse 019016865a (frontend) add e2e tests for entitlement disclaimers
Cover visibility rules (enabled / disabled / flagged reasons), the
seen-flag lifecycle, the showPotentialOperators branch with and
without signupUrl, and the OK-click close interaction.
2026-04-29 10:39:31 +02:00
Nathan Vasse ef675df5a2 (frontend) add entitlement disclaimer modal
Show a one-shot modal when the user's can_upload is blocked for a
recoverable reason (not_activated / no_organization), with an optional
list of potential operators where they can self-register. Tracks
"seen" per disclaimer in localStorage so users are not nagged on
every load, but re-shows the disclaimer if the underlying entitlement
changes and then regresses.
2026-04-29 10:26:54 +02:00
Nathan Vasse 6a19b0922e (frontend) type entitlement reason and context
Type the new backend fields (\`can_upload.reason\`, \`context\`) and
the new \`FRONTEND_ENTITLEMENTS_DISCLAIMERS\` config key so downstream
components can consume them with no casts.
2026-04-29 10:17:25 +02:00
Nathan Vasse ba4558e1ca (backend) expose FRONTEND_ENTITLEMENTS_DISCLAIMERS config
Add a dict-shaped config exposed to the frontend so operators can
enable or disable entitlement disclaimers per reason without code
changes. Also pin the Test settings to the local entitlements backend
so test runs do not depend on external state.
2026-04-29 10:17:25 +02:00
Nathan Vasse aa099068e9 (backend) add organization metrics to usage API
Add account_type=organization support to the usage metrics
endpoint. When requested, the API filters users by a shared
OIDC claim (account_id_key/account_id_value) and returns
aggregated storage across all matching users.

Add handling of account_id_key/account_id_value pair, allowing
filtering on allowed parameters in a more generic way. At the
moment `account_email` filter is still needed.

Also include the context of the entitlement in the /entitlements
response.
2026-04-29 10:17:25 +02:00
Nathan Vasse 8360aeca88 ♻️(backend) accept a queryset in storage compute backend
Change compute_storage_used signature from a single user
to a queryset of users. This enables aggregating storage
usage across multiple users, which is needed for
organization-level metrics.
2026-04-29 10:17:25 +02:00
Nathan Vasse 62b8341dd7 ♻️(backend) refactor entitlements into backend package
Restructure the entitlements module from flat files into a
backends/ package with a factory pattern. This enables
constructor kwargs injection for backend configuration.

Rename ANCT backend to DeployCenter to match the actual
service name, and rename Dummy backend to Static for clarity.
The factory now passes ENTITLEMENTS_BACKEND_PARAMETERS to
the backend constructor, making configuration more explicit
and testable.

Some request parameters get updated because of changes on
deploy center side that need to be reflected in services.
2026-04-29 10:17:25 +02:00
renovate[bot]andGitHub 39963b1332 ⬆️(dependencies) update python dependencies 2026-04-27 02:11:45 +00:00
Manuel Raynaud 805ef77521 🔥(backend) remove mirroring feature
The mirroring feature was hard to maintain and not performant. We should
rely on external tools made for that like RClone.
2026-04-23 17:42:48 +02:00
Manuel Raynaud 3ca5b0e296 🔖(minor) bump release version 0.17.0
Added

- (backend) make invitation validity duration configurable via env var
- (frontend) enhance upload toast with progress, errors and cancel support
- (frontend) add ErrorIcon component and support numeric icon sizes
- (frontend) make file upload abortable in driver layer
- (frontend) files preview v2
- 🔧(project) add DJANGO_EMAIL_URL_APP environment variable

Fixed

- 🐛(frontend) add actions menu on mobile My Files page
- 🐛(frontend) show actual selection count in hard delete modal
- 🐛(frontend) Responsive broken with long filters in search #659
- 🐛(front) set size and variant on trash navigate modal #666
- 🐛(frontend) fix uploads continuing after parent folder deletion
- 🐛(frontend) fix SDK picker link reach promotion
- 🐛(backend) route share invitation link to file view for files
- 🐛(frontend) fix "+ New" menu in read-only folders and virtual tabs
- 🐛(frontend) range selection freezes when there are many items in the list
- 🐛(backend) fix openapi schema for item access endpoints
- 🐛(backend) load jwks url when OIDC_RS_PRIVATE_KEY_STR is set
v0.17.0-preprod v0.17.0
2026-04-23 15:43:49 +02:00
Nathan Panchout 3731033f5b 🔧(project) add DJANGO_EMAIL_URL_APP environment variable
Share invitation emails embedded `Site.domain` directly, producing
schemeless links that mail clients failed to resolve. Introduce a
`DJANGO_EMAIL_URL_APP` environment variable holding the app's
absolute URL used when building invitation links, with a fallback
on the current Site domain when unset. Wire it in dev env, helm
dev values, the helm example and the env reference.
2026-04-23 12:05:26 +02:00
Nathan Panchout af8ba1031f 🐛(backend) route share invitation link to file view for files
Clicking the invitation link for a shared file opened the folder
explorer page with an empty children listing, because
`Item.send_email` hardcoded `/explorer/items/<uuid>/` regardless of
the item type.

Branch on `item.type` to use the dedicated file route
`/explorer/items/files/<uuid>/` already served by nginx and used by
the in-app share-link copy button.
2026-04-23 12:05:23 +02:00
Nathan Vasse 77a67db6d8 (frontend) add e2e tests for SDK picker selection
Cover the two main picker outcomes: cancelling leaves the item
private, and confirming exposes a publicly reachable URL. The
reach check opens the returned URL in a fresh anonymous context
and waits for the download event, since the backend serves
attachments with Content-Disposition and navigation aborts.

To run the test in CI, build the drive SDK package and start the
sdk-consumer dev server before the playwright job.
2026-04-22 16:00:15 +02:00
Nathan Vasse a12771fe08 🐛(frontend) fix SDK picker link reach promotion
Switch to useMutationUpdateLinkConfiguration and preserve the
item's existing link_role. Also add the missing sdk.explorer.cancel
translations for en and nl so the Cancel button label renders
correctly. This should have been done when migration to this new
API route. The existing update did not have any effect.
2026-04-22 16:00:15 +02:00
Manuel Raynaud d120171944 🐛(backend) load jwks url when OIDC_RS_PRIVATE_KEY_STR is set
When the resource server is enabled and the backend used is
JWTResourceServerBackend, then the API should expose a JWKS endpoint
to share the RSA public key to the OIDC provider. Everything is made
in the Django LaSuite library, but the URL is not included in the
Drive URLs. This commit adds it when the setting OIDC_RS_PRIVATE_KEY_STR
is set.
2026-04-22 13:37:30 +02:00
renovate[bot]andGitHub d3cb848448 ⬆️(dependencies) update pytest to v9.0.3 [SECURITY] 2026-04-22 10:22:45 +00:00
Nathan Vasse 352e19580e (backend) make invitation validity duration configurable via env
The invitation validity duration was hardcoded to 7 days. Expose it as
an INVITATION_VALIDITY_DURATION env var so operators can tune it per
deployment without patching settings. Default remains 7 days.
2026-04-22 10:09:31 +02:00
renovate[bot]andNathan Vasse 6cc9c4de9c ⬆️(dependencies) update vite to v6.4.2 [SECURITY] 2026-04-21 14:38:00 +02:00
renovate[bot]andNathan Vasse bb1a018e21 ⬆️(dependencies) update next to v15.5.15 [SECURITY] 2026-04-21 11:48:51 +02:00
Nathan Vasse 6655b8fbe8 🐛(backend) fix openapi schema for item access endpoints
`ItemAccessViewSet.get_serializer_class` depends on `self.item`, which
reads `self.kwargs["resource_id"]`. This is unavailable during
drf-spectacular introspection, so spectacular fails to resolve the
serializer and drops the requestBody for POST/PUT/PATCH operations.

Declare the schema statically via `@extend_schema` and
`@extend_schema_view` so the generated OpenAPI exposes the proper
request and response payloads for item access endpoints.
2026-04-21 10:24:18 +02:00
Nathan Panchout 5966e14c46 🐛(frontend) fix range selection freeze on large folders
Drop selectedItems / selectedItemsMap from GlobalExplorerContext and
move every call-site to the selection store introduced in the previous
commit. Rows of the embedded explorer grid are extracted into a memoed
EmbeddedExplorerGridRow that subscribes to its own id via
useIsItemSelected, and the name/actions/mobile cells are memoed and
read their selection status the same way.

High-level consumers that only need a boolean or a count use
useHasSelection / useSelectionCount so they no longer re-render on
every marquee tick:

- AppExplorerInner uses useHasSelection to toggle the selection bar
- ExplorerDndProvider splits the count consumers into dedicated child
  components (drag overlay and move confirmation modal)
- useTableKeyboardNavigation subscribes imperatively through
  selectionStore.subscribe so the focus effect runs without
  invalidating the host component

EmbeddedExplorer creates its own local store so the move modal and the
SDK picker keep their selection scoped and do not leak into the main
explorer selection.

Fixes #124
2026-04-20 17:09:53 +02:00
Nathan Panchout 3bae4e7d3b (frontend) add explorer selection store with per-id listeners
Introduce a lightweight external store compatible with
useSyncExternalStore. It exposes:

- a global subscription for consumers that need the full list or count
- per-id subscriptions so a row can bail out automatically when its own
  isSelected boolean has not changed
- setSelectedItems that diffs the previous and next id maps and
  notifies only the listeners whose status actually flipped

No React state, no context fan-out: a marquee tick that flips N rows
notifies exactly N listeners instead of invalidating the whole tree.
2026-04-20 17:09:53 +02:00
Nathan Panchout 3a730b87cf 📝(frontend) document explorer selection store architecture
Add an architecture doc covering the rationale behind the selection
store refactor: why React Context did not scale to 200+ rows during a
marquee drag, why useSyncExternalStore with per-id listeners enables
automatic bailout, and how global vs embedded scopes are wired.

Lives under docs/architecture/ for long-term reference.
2026-04-20 17:09:53 +02:00
Nathan Panchout 7ef7d56317 (front) add e2e tests for "+ New" fallback to My Files
Cover the four scenarios of the new "+ New" behavior:
- folder creation from a read-only shared folder redirects into the
  newly created folder under My Files
- document creation from a read-only shared folder redirects to the
  My Files view with the new file listed
- folder creation from the Recent / Shared with me / Starred virtual
  tabs creates in My Files
- folder creation in a writable folder still happens in place, with
  no fallback redirect
2026-04-20 15:58:53 +02:00
Nathan Panchout faee0de673 🐛(front) fix "+ New" menu in read-only folders and virtual tabs
The "+ New" dropdown used to hide all its entries when the user lacked
children_create on the current folder, leaving an empty popover. On
virtual tabs (Recent, My Files, Shared with me, Starred) there is no
real current folder either, so the same empty state could be reached.

Always populate the menu and, when the user cannot create in place,
fall back to creating the item in "My Files" (no parent). After a
fallback creation we redirect:
- into the new folder for folder creation
- to the My Files view for file creation, since a file is not a
  navigable route
The new item is pre-selected in both cases.
2026-04-20 15:58:53 +02:00
Nathan Vasse 26a522f2ae 🔧(ci) exclude ts file from print job
This job was detecting some legit code as false positive
for print statements.
2026-04-20 15:21:01 +02:00
Nathan Vasse eefa620702 (other) route /wopi/<uuid> to the WOPI item page
The WOPI page is a dynamic route keyed by item UUID, so nginx needs to
fall back to the [id].html shell when the URL is hit directly (reload,
external link). Mirrors the existing /explorer/items/[id] rule.
2026-04-20 15:01:56 +02:00
Nathan Vasse a8e71cdb38 (backend) add filename to e2e search fixtures
The search e2e fixture items lacked a filename, which made the seeded
file items diverge from real uploads where the filename is present.
We need the filename to be predictive so we can make assertion in the
e2e tests about the viewer that should open or not.
2026-04-20 15:01:56 +02:00
Nathan Vasse 7280b972c4 ♻️(frontend) small cleanups in file preview and wopi
Drop a redundant clearTimeout guard, reformat the WopiEditorFrame
props, assert launch_url is defined at render time, and add a comment
clarifying the WOPI page spinner branch.
2026-04-20 15:01:42 +02:00
Nathan Vasse 3030f71189 ♻️(frontend) unify preview messages into a shared component
The error, not-supported, suspicious and WOPI placeholder viewers all
rendered the same "icon + title + description + action" layout with
near-duplicate scss. Extract a PreviewMessage component so styling and
backdrop-close behaviour live in one place, and update the e2e
selectors to match the new markup.
2026-04-20 15:01:33 +02:00
Nathan Vasse 788cdba513 (frontend) add e2e tests for preview backdrop close
Cover the backdrop-click-to-close behavior for both image
and PDF viewers: clicking the backdrop closes the preview,
clicking the content does not, and dragging across the image
viewer does not trigger a close.
2026-04-20 15:01:33 +02:00
Nathan Vasse afb4d2862d (frontend) close file preview on backdrop click
Users can now dismiss the preview by clicking the blurry area
around the content. Each viewer marks its backdrop zones with
a data attribute so the handler in FilesPreview can distinguish
backdrop from content clicks. The image viewer also guards
against accidental close during pan-drag gestures.
2026-04-20 15:01:33 +02:00
Nathan Vasse b69e0fc218 (frontend) add e2e test for image print via hidden iframe
Ensures Print on an image creates a hidden iframe that loads the
same preview URL, waits for the image to decode, and calls
window.print() — all without opening a new tab.
2026-04-20 15:01:33 +02:00
Nathan Vasse 49c0821281 (frontend) print images via browser dialog instead of new tab
Previously clicking Print on an image opened it in a new tab,
leaving the user to trigger the print dialog themselves. Now a
hidden iframe loads the image and calls window.print() directly.
2026-04-20 15:01:33 +02:00
Nathan Vasse 140fb16292 (frontend) improve file preview e2e test stability
Switch the non-printable file test from DOCX to an audio
file so it no longer relies on WOPI (which opens in a new
tab). Wait for the PDF page to render before interacting
with the page input to avoid flaky failures. Remove an
unused variable.
2026-04-20 15:01:33 +02:00
Nathan Vasse 3c46a909e5 ♻️(frontend) remove unused props and CSS in preview viewers
Remove the unused isSidebarOpen prop from PdfControls and
strip unnecessary position/min-height rules from the video
player that were left over from earlier layout iterations.
2026-04-20 15:01:33 +02:00
Nathan Vasse e6c657ced4 🐛(frontend) fix preview not updating on data change
Add data to the useEffect dependency array so the current
file index is recalculated when the file list changes,
e.g. after a refetch or when items are added/removed.
2026-04-20 15:01:33 +02:00
Nathan Vasse 77174705ea 🐛(frontend) fix image flash when navigating previews
Add a key prop to force React to remount the img element
when switching files. Without this, transitioning between
images of very different sizes causes a visual splash.
2026-04-20 15:01:33 +02:00
Nathan Vasse 26418bda18 💄(frontend) fix preview title layout and use design token
Extract a wrapper div for flex layout and overflow handling,
keeping the title element focused on typography. Replace the
hardcoded color with a design system variable for consistency.
2026-04-20 15:01:33 +02:00
Nathan Vasse 3f439a66ad (frontend) update wopi e2e tests for new-tab flow
Follow the WOPI-in-new-tab change: the double-click scenario now
asserts that a new page opens with the office iframe and that the
preview modal stays closed, a new test covers the "Open in editor"
placeholder reached by keyboard navigating onto a WOPI file, and the
copy/paste scenario drives the detached wopiPage. Refresh canvas
snapshots accordingly and drop the obsolete per-spec snapshot copies.
2026-04-20 15:01:33 +02:00
Nathan Vasse 42c34036e4 (frontend) open WOPI files in a new tab
WOPI editors (OnlyOffice / Collabora) work better as a full-page
experience than embedded inside the preview modal. Double-clicking a
WOPI file in the grid or activating one from the search modal now
opens /wopi/:id in a new tab. The preview modal still shows an
"Open in editor" placeholder when a user navigates onto a WOPI file
via keyboard, so the preview flow stays consistent.

The former WopiEditor component is renamed WopiEditorFrame and
hosted on the new page. The inline rename-sync path is removed
because the editor no longer lives inside the items list.
2026-04-20 15:01:33 +02:00
Nathan Vasse f90c5c8b3a 💄(frontend) localize image viewer loading label
The loading spinner label was hardcoded in French. Use the translated
file_preview.image.loading key so other locales render correctly.
2026-04-20 15:01:33 +02:00
Nathan Vasse d3c522058e 🌐(frontend) add wopi open in editor and image loading translations
Add the en/fr/nl entries needed by the upcoming WOPI "open in editor"
placeholder and the image viewer loading label.
2026-04-20 15:01:33 +02:00
Nathan Vasse c288414827 🐛(frontend) clear pdf sidebar timeout on unmount
The effect that toggles the pdf-sidebar class scheduled a setTimeout
without returning a cleanup, so the timer could fire after the file
preview unmounted. Capture the timeout id and clear it on cleanup.
2026-04-20 15:01:33 +02:00
Nathan Vasse 3670cefb30 ♻️(frontend) rename ProgressBar to DurationBar in preview
The component lives in DurationBar.tsx but was exported as ProgressBar,
which was confusing. Rename the export and update the two call sites
in AudioPlayer and VideoPlayer.
2026-04-20 15:01:33 +02:00
Nathan Vasse 30cfcc7f46 📝(doc) update changelog
Add entry about the file preview v2 iteration.
2026-04-20 15:01:33 +02:00
Nathan Vasse 48ea4c0533 (frontend) add unsupported file preview e2e tests
Cover the fallback viewer that kicks in for file types the app
cannot render inline. A minimal .bin fixture exercises the redesign
so the filename, the "Unsupported format." disclaimer and the
secondary download button are all checked end to end.
2026-04-20 15:01:33 +02:00
Nathan Vasse b203aa17de (frontend) add video preview e2e tests
Cover the video viewer with a dedicated spec that uploads a small
mp4 fixture, opens the preview and exercises the player controls.
Keeps the new viewer types consistently covered alongside the audio
and image specs.
2026-04-20 15:01:32 +02:00
Nathan Vasse 07ca57c79b (frontend) add image preview e2e tests
Cover the image viewer with a dedicated spec that uploads a small
png fixture, opens the preview and asserts the image renders and
reacts to the viewer controls. Mirrors the audio/video specs so
each viewer has its own file.
2026-04-20 15:01:32 +02:00
Nathan Vasse 43cb816e5d (frontend) add audio preview e2e tests
Cover the audio viewer with a dedicated spec that uploads a small
mp3 fixture, opens the preview and checks the playback controls.
Ensures the audio branch of the preview rewrite stays covered as we
iterate on the other viewers.
2026-04-20 15:01:32 +02:00