From c2cb7556a51c5b2f4a5369c3c00469cb6c780752 Mon Sep 17 00:00:00 2001 From: titagass <269501527+titagass@users.noreply.github.com> Date: Thu, 2 Apr 2026 18:00:21 +0000 Subject: [PATCH] fix(wopi): fallback to view mode for pdf files --- static/js/features/files/wopiEditor.js | 29 ++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/static/js/features/files/wopiEditor.js b/static/js/features/files/wopiEditor.js index 3fd8eb59..b752c714 100644 --- a/static/js/features/files/wopiEditor.js +++ b/static/js/features/files/wopiEditor.js @@ -28,7 +28,7 @@ class WopiEditor { async openInModal(fileId, fileName, action) { action = action || 'edit'; try { - var data = await this._getEditorUrl(fileId, action); + var data = await this._getEditorUrlWithFallback(fileId, fileName, action); this._showModal(data, fileName); } catch (error) { console.error('Failed to open WOPI editor:', error); @@ -44,7 +44,7 @@ class WopiEditor { async openInTab(fileId, fileName, action) { action = action || 'edit'; try { - var data = await this._getEditorUrl(fileId, action); + var data = await this._getEditorUrlWithFallback(fileId, fileName, action); var hostUrl = '/wopi/edit/' + encodeURIComponent(fileId) + '?access_token=' + encodeURIComponent(data.access_token); window.open(hostUrl, '_blank'); @@ -71,6 +71,31 @@ class WopiEditor { return response.json(); } + /** + * Some WOPI file types, such as PDFs, are view-only. + * If an edit request returns 422, retry once in view mode. + */ + async _getEditorUrlWithFallback(fileId, fileName, action) { + try { + return await this._getEditorUrl(fileId, action); + } catch (error) { + if (!this._shouldRetryInViewMode(fileName, action, error)) { + throw error; + } + + return this._getEditorUrl(fileId, 'view'); + } + } + + _shouldRetryInViewMode(fileName, action, error) { + if (action !== 'edit' || !error || !error.message) { + return false; + } + + var ext = fileName.split('.').pop().toLowerCase(); + return ext === 'pdf' && error.message.indexOf('422') !== -1; + } + /** * Show the editor in a full-screen modal with iframe. */