From 9290aea59141df95e5da34e220ad907b857ebcfb Mon Sep 17 00:00:00 2001 From: Dionisio Date: Sat, 14 Feb 2026 11:06:29 +0100 Subject: [PATCH] fix(#107): trash/recent/favorites list view rendering bugs Trash view: - Fix 'Invalid Date': use item.trashed_at (ISO 8601) instead of item.deleted_at * 1000 - Fix literal i18n key 'files.file_types.file': determine type from file extension (pdf, image, video, audio, text, document) since trash DTO has no mime_type - Fix column alignment: remove checkbox from trash header (not applicable), add .trash-header CSS class matching the 5-column grid layout Recent view: - Fix header/row column misalignment: add empty placeholder div for indicator column and .recent-header CSS class matching the 5-column grid - Fix missing i18n key: use 'recent.accessed' instead of 'files.last_accessed' - Fix default typeLabel not internationalized: use i18n.t('files.file_types.document') Favorites view: - Fix header/row column misalignment: add empty placeholder div for indicator column and .favorites-header CSS class matching the 5-column grid - Fix default typeLabel not internationalized: use i18n.t('files.file_types.document') Bump SW cache to v11. --- static/css/favorites.css | 4 ++++ static/css/recent.css | 4 ++++ static/css/style.css | 8 ++++++-- static/js/app.js | 44 ++++++++++++++++++++++++++++++++-------- static/js/favorites.js | 5 +++-- static/js/recent.js | 7 ++++--- static/sw.js | 2 +- 7 files changed, 57 insertions(+), 17 deletions(-) diff --git a/static/css/favorites.css b/static/css/favorites.css index d66aea02..aa21dc8e 100644 --- a/static/css/favorites.css +++ b/static/css/favorites.css @@ -47,6 +47,10 @@ } /* Adjustments for list view */ +.list-header.favorites-header { + grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; +} + .file-item.favorite-item { position: relative; grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; diff --git a/static/css/recent.css b/static/css/recent.css index 7da7ef71..008907f0 100644 --- a/static/css/recent.css +++ b/static/css/recent.css @@ -36,6 +36,10 @@ } /* Adjustments for list view */ +.list-header.recent-header { + grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; +} + .file-item.recent-item { position: relative; grid-template-columns: 30px minmax(200px, 2fr) 1fr 1fr 120px; diff --git a/static/css/style.css b/static/css/style.css index 0753abad..e6107067 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1811,9 +1811,13 @@ select:focus { background-color: #fff0ec; } -/* For trash mode, adjust columns */ +/* For trash mode, adjust columns (5 cols: name, type, path, date, actions) */ +.list-header.trash-header { + grid-template-columns: minmax(180px, 1.5fr) 0.5fr 1fr 140px 100px; +} + .trash-item.file-item { - grid-template-columns: minmax(180px, 1.5fr) 0.5fr 1fr 120px 100px; + grid-template-columns: minmax(180px, 1.5fr) 0.5fr 1fr 140px 100px; } .file-item:hover { diff --git a/static/js/app.js b/static/js/app.js index f6daebd5..e901f9f7 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -874,8 +874,7 @@ async function loadTrashItems() { if (window.multiSelect) window.multiSelect.clear(); elements.filesGrid.innerHTML = ''; elements.filesListView.innerHTML = ` -
-
+
Name
Type
Original location
@@ -924,17 +923,44 @@ async function loadTrashItems() { */ function addTrashItemToView(item) { const isFile = item.item_type === 'file'; - const iconClass = isFile ? 'fas fa-file' : 'fas fa-folder'; - // Format date - const deletedDate = new Date(item.deleted_at * 1000); + // Format date - backend sends trashed_at as ISO 8601 string + const deletedDate = new Date(item.trashed_at); const formattedDate = deletedDate.toLocaleDateString() + ' ' + deletedDate.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); - // Item type label - const typeLabel = isFile ? - (window.i18n ? window.i18n.t('files.file_types.file') : 'File') : - (window.i18n ? window.i18n.t('files.file_types.folder') : 'Folder'); + // Determine type label and icon from extension (trash DTO has no mime_type) + let typeLabel; + let iconClass; + if (!isFile) { + iconClass = 'fas fa-folder'; + typeLabel = window.i18n ? window.i18n.t('files.file_types.folder') : 'Folder'; + } else { + const ext = (item.name.split('.').pop() || '').toLowerCase(); + const imageExts = ['jpg','jpeg','png','gif','bmp','svg','webp','ico','tiff']; + const videoExts = ['mp4','avi','mkv','mov','wmv','flv','webm']; + const audioExts = ['mp3','wav','ogg','flac','aac','wma','m4a']; + const textExts = ['txt','md','csv','log','ini','cfg','conf']; + if (ext === 'pdf') { + iconClass = 'fas fa-file-pdf'; + typeLabel = window.i18n ? window.i18n.t('files.file_types.pdf') : 'PDF'; + } else if (imageExts.includes(ext)) { + iconClass = 'fas fa-file-image'; + typeLabel = window.i18n ? window.i18n.t('files.file_types.image') : 'Image'; + } else if (videoExts.includes(ext)) { + iconClass = 'fas fa-file-video'; + typeLabel = window.i18n ? window.i18n.t('files.file_types.video') : 'Video'; + } else if (audioExts.includes(ext)) { + iconClass = 'fas fa-file-audio'; + typeLabel = window.i18n ? window.i18n.t('files.file_types.audio') : 'Audio'; + } else if (textExts.includes(ext)) { + iconClass = 'fas fa-file-alt'; + typeLabel = window.i18n ? window.i18n.t('files.file_types.text') : 'Text'; + } else { + iconClass = 'fas fa-file'; + typeLabel = window.i18n ? window.i18n.t('files.file_types.document') : 'Document'; + } + } // Grid view element const gridElement = document.createElement('div'); diff --git a/static/js/favorites.js b/static/js/favorites.js index 87760c64..ad6d6328 100644 --- a/static/js/favorites.js +++ b/static/js/favorites.js @@ -320,7 +320,8 @@ const favorites = { filesGrid.innerHTML = ''; filesListView.innerHTML = ` -
+
+
Name
Type
Size
@@ -556,7 +557,7 @@ const favorites = { // Determine icon and type let iconClass = 'fas fa-file'; let iconSpecialClass = ''; - let typeLabel = 'Document'; + let typeLabel = window.i18n ? window.i18n.t('files.file_types.document') : 'Document'; if (file.mime_type) { if (file.mime_type.startsWith('image/')) { diff --git a/static/js/recent.js b/static/js/recent.js index 097d8e52..04b5fd37 100644 --- a/static/js/recent.js +++ b/static/js/recent.js @@ -109,11 +109,12 @@ const recent = { filesGrid.innerHTML = ''; filesListView.innerHTML = ` -
+
+
Name
Type
Size
-
Last accessed
+
Accessed
`; @@ -157,7 +158,7 @@ const recent = { // Determine icon and type let iconClass = 'fas fa-file'; let iconSpecialClass = ''; - let typeLabel = 'Document'; + let typeLabel = window.i18n ? window.i18n.t('files.file_types.document') : 'Document'; if (file.mime_type) { if (file.mime_type.startsWith('image/')) { diff --git a/static/sw.js b/static/sw.js index 59cfc859..9b433c69 100644 --- a/static/sw.js +++ b/static/sw.js @@ -1,5 +1,5 @@ // OxiCloud Service Worker -const CACHE_NAME = 'oxicloud-cache-v10'; +const CACHE_NAME = 'oxicloud-cache-v11'; const ASSETS_TO_CACHE = [ '/', '/index.html',