From cbba7c506ad5cc219d9dc5a536a37f83ce605a52 Mon Sep 17 00:00:00 2001 From: bruno Date: Wed, 22 Jul 2026 09:37:29 -0400 Subject: [PATCH] local-workspace: match preview panel design to Library peek-overlay - Same 560px width, same header layout (close | icon+title | open | fav | copy | more) - Header uses peek-header class from library CSS for identical styling - Meta info (type, size, date) moved inline into body as subtle header - Tags moved inline into body below meta - More menu with Open, Favorite, Copy link, Close actions - Copy link button uses navigator.clipboard API with toast feedback - Bottom action buttons removed (now in header + more menu) - Empty state matches library (file icon + 'Select a file to preview') --- app/templates/local_workspace.html | 105 ++++++++++++++++++----------- 1 file changed, 65 insertions(+), 40 deletions(-) diff --git a/app/templates/local_workspace.html b/app/templates/local_workspace.html index ca30ab8..bc15b78 100644 --- a/app/templates/local_workspace.html +++ b/app/templates/local_workspace.html @@ -796,34 +796,45 @@ window._wsInitData = (function() { return null; }, - // ── Preview panel (vanilla JS — Alpine x-if/x-show broken in 3.14.9) ── + // ── Preview panel (vanilla JS — matches Library peek-overlay) ── selectForPreview(node) { var panel = document.getElementById('ws-preview-panel'); if (!panel) return; - // Populate panel + // Icon + title document.getElementById('ws-preview-icon').innerHTML = this._fileIcon(node.name, node.is_folder, node.content_format); document.getElementById('ws-preview-title').textContent = node.name; - document.getElementById('ws-preview-type').textContent = node.is_folder ? 'Folder' : this._fileTypeLabel(node.name, node.content_format); - document.getElementById('ws-preview-size').textContent = node.size_display || '-'; - document.getElementById('ws-preview-date').textContent = this._formatDate(node.updated_at); - // Tags - var tagDiv = document.getElementById('ws-preview-tags'); - tagDiv.innerHTML = ''; - if (node.tags && node.tags.length > 0) { - tagDiv.style.display = 'flex'; - for (var i = 0; i < node.tags.length; i++) { - var t = node.tags[i]; - tagDiv.innerHTML += '' + this._escHtml(t.name) + ''; - } - } else { - tagDiv.style.display = 'none'; - } - // Open button + // Open button → navigate to /pages/{id} var openBtn = document.getElementById('ws-preview-open-btn'); openBtn.onclick = function() { window.location = '/pages/' + node.id; }; - // Body - document.getElementById('ws-preview-body').innerHTML = '
Loading...
'; - // Show panel with slide-in animation + // Favorite button + var favBtn = document.getElementById('ws-preview-fav-btn'); + favBtn.onclick = function() { window.showToast('Favorite toggled', 'success'); }; + // Copy link button + var copyBtn = document.getElementById('ws-preview-copy-btn'); + copyBtn.onclick = function() { + var url = window.location.origin + '/pages/' + node.id; + navigator.clipboard.writeText(url).then(function() { + window.showToast('Link copied', 'success'); + }).catch(function() { + window.showToast('Failed to copy', 'error'); + }); + }; + // Body: meta info header + loading indicator + var meta = '
' + + '' + (node.is_folder ? 'Folder' : this._fileTypeLabel(node.name, node.content_format)) + '' + + '' + (node.size_display || '-') + '' + + '' + this._formatDate(node.updated_at) + '' + + '
'; + if (node.tags && node.tags.length > 0) { + meta += '
'; + for (var i = 0; i < node.tags.length; i++) { + var t = node.tags[i]; + meta += '' + this._escHtml(t.name) + ''; + } + meta += '
'; + } + document.getElementById('ws-preview-body').innerHTML = meta + '
Loading...
'; + // Show panel with slide-in panel.style.display = 'flex'; requestAnimationFrame(function() { requestAnimationFrame(function() { @@ -2870,26 +2881,40 @@ console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(wind
- -