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')
This commit is contained in:
@@ -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 += '<span class=\"tag-chip\" style=\"background:' + this._escHtml(t.color) + '\">' + this._escHtml(t.name) + '</span>';
|
||||
}
|
||||
} 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 = '<div style=\"text-align:center;padding:40px;color:var(--text-tertiary)\">Loading...</div>';
|
||||
// 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 = '<div style="display:flex;gap:16px;flex-wrap:wrap;padding-bottom:12px;margin-bottom:12px;border-bottom:1px solid var(--border);font-size:12px;color:var(--text-tertiary);">'
|
||||
+ '<span>' + (node.is_folder ? 'Folder' : this._fileTypeLabel(node.name, node.content_format)) + '</span>'
|
||||
+ '<span>' + (node.size_display || '-') + '</span>'
|
||||
+ '<span>' + this._formatDate(node.updated_at) + '</span>'
|
||||
+ '</div>';
|
||||
if (node.tags && node.tags.length > 0) {
|
||||
meta += '<div style="display:flex;gap:4px;flex-wrap:wrap;margin-bottom:12px;">';
|
||||
for (var i = 0; i < node.tags.length; i++) {
|
||||
var t = node.tags[i];
|
||||
meta += '<span class="tag-chip" style="background:' + this._escHtml(t.color) + '">' + this._escHtml(t.name) + '</span>';
|
||||
}
|
||||
meta += '</div>';
|
||||
}
|
||||
document.getElementById('ws-preview-body').innerHTML = meta + '<div style="text-align:center;padding:40px;color:var(--text-tertiary)">Loading...</div>';
|
||||
// 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
|
||||
<div class="file-preview-body" x-html="previewContent"></div>
|
||||
</div>
|
||||
|
||||
<!-- Preview Panel — fixed overlay (like Library side peek) -->
|
||||
<div id="ws-preview-panel" style="position:fixed;top:0;right:0;width:480px;max-width:90vw;height:100vh;z-index:500;display:none;flex-direction:column;background:var(--bg-modal);border-left:1px solid var(--border);box-shadow:-8px 0 32px rgba(0,0,0,0.25);transform:translateX(100%);transition:transform 0.2s cubic-bezier(0.16,1,0.3,1);">
|
||||
<div class="preview-panel-header" style="display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--border);flex-shrink:0;">
|
||||
<span id="ws-preview-icon"></span>
|
||||
<span style="font-size:15px;font-weight:600;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" id="ws-preview-title"></span>
|
||||
<button class="preview-close" onclick="window._wsData.closePreviewPanel()" title="Close preview" style="background:none;border:none;color:var(--text-tertiary);font-size:20px;cursor:pointer;padding:2px 6px;border-radius:4px;line-height:1;">×</button>
|
||||
<!-- Preview Panel — identical to Library peek-overlay -->
|
||||
<div id="ws-preview-panel" style="position:fixed;top:0;right:0;width:560px;max-width:90vw;height:100vh;background:var(--bg-modal);border-left:1px solid var(--border);box-shadow:-8px 0 32px rgba(0,0,0,0.25);z-index:500;display:none;flex-direction:column;transform:translateX(100%);transition:transform 0.2s cubic-bezier(0.16,1,0.3,1);">
|
||||
<div class="peek-header">
|
||||
<button onclick="window._wsData.closePreviewPanel()" title="Close" style="background:transparent;border:none;color:var(--text-secondary);cursor:pointer;padding:6px;border-radius:4px;display:flex;align-items:center;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:15px;height:15px;"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
||||
</button>
|
||||
<div class="peek-title" style="flex:1;font-size:15px;font-weight:600;color:var(--text-primary);display:flex;align-items:center;gap:8px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;">
|
||||
<span id="ws-preview-icon"></span>
|
||||
<span id="ws-preview-title"></span>
|
||||
</div>
|
||||
<button id="ws-preview-open-btn" title="Open full page" style="background:transparent;border:none;color:var(--text-secondary);cursor:pointer;padding:6px;border-radius:4px;display:flex;align-items:center;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:15px;height:15px;"><path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
|
||||
</button>
|
||||
<button id="ws-preview-fav-btn" title="Favorite" style="background:transparent;border:none;color:var(--text-secondary);cursor:pointer;padding:6px;border-radius:4px;display:flex;align-items:center;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:15px;height:15px;"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
|
||||
</button>
|
||||
<button id="ws-preview-copy-btn" title="Copy link" style="background:transparent;border:none;color:var(--text-secondary);cursor:pointer;padding:6px;border-radius:4px;display:flex;align-items:center;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:15px;height:15px;"><path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/></svg>
|
||||
</button>
|
||||
<div style="position:relative;">
|
||||
<button onclick="var m=document.getElementById('ws-preview-more-menu');m.style.display=m.style.display==='block'?'none':'block';" title="More" style="background:transparent;border:none;color:var(--text-secondary);cursor:pointer;padding:6px;border-radius:4px;display:flex;align-items:center;">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:15px;height:15px;"><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></svg>
|
||||
</button>
|
||||
<div id="ws-preview-more-menu" class="more-menu" style="display:none;right:0;top:100%;min-width:180px;">
|
||||
<div class="menu-item" onclick="document.getElementById('ws-preview-open-btn').click();document.getElementById('ws-preview-more-menu').style.display='none';">{{ fd_icon("external-link",14) }} Open</div>
|
||||
<div class="menu-item" onclick="document.getElementById('ws-preview-fav-btn').click();document.getElementById('ws-preview-more-menu').style.display='none';">{{ fd_icon("star",14) }} Favorite</div>
|
||||
<div class="menu-item" onclick="document.getElementById('ws-preview-copy-btn').click();document.getElementById('ws-preview-more-menu').style.display='none';">{{ fd_icon("link",14) }} Copy link</div>
|
||||
<div class="more-sep"></div>
|
||||
<div class="menu-item menu-danger" onclick="window._wsData.closePreviewPanel();document.getElementById('ws-preview-more-menu').style.display='none';">{{ fd_icon("trash",14) }} Close</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:12px;padding:8px 16px;font-size:12px;color:var(--text-tertiary);border-bottom:1px solid var(--border);flex-shrink:0;">
|
||||
<span id="ws-preview-type"></span>
|
||||
<span id="ws-preview-size"></span>
|
||||
<span id="ws-preview-date"></span>
|
||||
</div>
|
||||
<div class="preview-panel-tags" id="ws-preview-tags" style="display:none;gap:4px;flex-wrap:wrap;padding:8px 16px;border-bottom:1px solid var(--border);flex-shrink:0;">
|
||||
</div>
|
||||
<div class="preview-panel-body" id="ws-preview-body" style="flex:1;overflow:auto;padding:16px;font-size:13px;line-height:1.6;color:var(--text);">
|
||||
<div style="text-align:center;padding:40px;color:var(--text-tertiary)">Select a file to preview</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--border);flex-shrink:0;">
|
||||
<button class="btn btn-secondary" id="ws-preview-open-btn">{{ fd_icon("file",14) }} Open</button>
|
||||
<button class="btn btn-secondary" onclick="window._wsData.closePreviewPanel()">{{ fd_icon("edit",14) }} Close</button>
|
||||
<div id="ws-preview-body" style="flex:1;overflow-y:auto;padding:16px 20px;">
|
||||
<div style="text-align:center;padding:60px 20px;color:var(--text-dim);">{{ fd_icon("file",32) }}<div style="margin-top:8px;font-size:14px;">Select a file to preview</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /ws-split -->
|
||||
|
||||
Reference in New Issue
Block a user