refactor: Shared Links als Card-Grid mit Card-Menü (wie Cronjobs)

- index.html: shared-links-list → card-grid
- dashboard.js: Cards mit card-compact, card-menu-dropdown, fa-cog statt fa-robot
- dashboard.css: 60 Zeilen shared-link-*/danger-icon CSS entfernt (nutzt card-Styles)
This commit is contained in:
Meleki committed 2026-03-05 15:11:05 +01:00
1 parent 38a8223228
commit 8a9293218b
3 files changed
+55 -84

No files matched your search

-60
View File
@@ -256,66 +256,6 @@
color: var(--text);
}
/* Shared Links */
.shared-links-list {
display: flex;
flex-direction: column;
gap: var(--badge-spacing);
}
.shared-link-row {
display: flex;
align-items: center;
gap: var(--box-spacing);
padding: var(--box-padding);
background: var(--f3-bg);
border: var(--border-width) solid var(--f3-border);
border-radius: var(--border-radius);
}
.shared-link-info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: calc(var(--badge-spacing) / 2);
}
.shared-link-preview {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.shared-link-preview .fa {
opacity: var(--semi-transparent);
margin-right: calc(var(--badge-spacing) / 2);
}
.shared-link-meta {
display: flex;
flex-wrap: wrap;
gap: var(--box-spacing);
opacity: var(--semi-transparent);
font-size: calc(var(--font-size) * 0.9);
}
.shared-link-actions {
display: flex;
gap: var(--badge-spacing);
flex-shrink: 0;
}
.danger-icon {
color: var(--dangerous);
opacity: var(--semi-transparent);
}
.danger-icon:hover {
opacity: 1;
}
/* Compact cards (no image) */
.card-compact {
padding: var(--box-padding);
+1 -1
View File
@@ -84,7 +84,7 @@
<div class="section-header">
<h2>Geteilte Links</h2>
</div>
<div class="shared-links-list" id="sharedLinksList"></div>
<div class="card-grid" id="sharedLinksCards"></div>
</section>
</div>
</div>
+54 -23
View File
@@ -329,45 +329,76 @@ registerPage('dashboard', {
// Shared Links
const shares = await apiListShares();
const sharedSection = document.getElementById('sharedLinksSection');
const sharedList = document.getElementById('sharedLinksList');
const sharedGrid = document.getElementById('sharedLinksCards');
if (shares.length > 0) {
sharedSection.hidden = false;
sharedList.innerHTML = '';
sharedGrid.innerHTML = '';
for (const s of shares) {
const row = document.createElement('div');
row.className = 'shared-link-row';
const card = document.createElement('div');
card.className = 'card card-compact';
const shareUrl = `${location.origin}/#shared/${s.shareToken}`;
const modeLabel = s.includeContext ? 'Thread' : 'Einzeln';
const roleIcon = s.role === 'user' ? 'fa-user' : 'fa-robot';
row.innerHTML = `
<div class="shared-link-info">
<span class="shared-link-preview"><i class="fa ${roleIcon}"></i> ${esc(s.preview || '(leer)')}</span>
<span class="shared-link-meta">
${s.sessionName ? `<span><i class="fa fa-comment"></i> ${esc(s.sessionName)}</span>` : ''}
<span><i class="fa fa-${s.includeContext ? 'comments' : 'comment-o'}"></i> ${modeLabel}</span>
<span><i class="fa fa-clock-o"></i> ${formatDate(s.createdAt)}</span>
</span>
const roleIcon = s.role === 'user' ? 'fa-user' : 'fa-cog';
card.innerHTML = `
<div class="card-body">
<div class="card-title-row">
<span class="card-title"><i class="fa ${roleIcon}"></i> ${esc(s.preview || '(leer)')}</span>
<div class="card-menu">
<button class="card-menu-trigger icon-btn"><i class="fa fa-ellipsis-v"></i></button>
<div class="card-menu-dropdown" hidden>
<button class="card-menu-item" data-action="copy"><i class="fa fa-clipboard"></i> Link kopieren</button>
<button class="card-menu-item" data-action="open"><i class="fa fa-external-link"></i> Öffnen</button>
<button class="card-menu-item" data-action="delete"><i class="fa fa-trash"></i> Löschen</button>
</div>
</div>
</div>
<div class="card-meta">
${s.sessionName ? `<span class="card-meta-item"><i class="fa fa-comment"></i> ${esc(s.sessionName)}</span>` : ''}
<span class="card-meta-item"><i class="fa fa-${s.includeContext ? 'comments' : 'comment-o'}"></i> ${modeLabel}</span>
<span class="card-meta-item"><i class="fa fa-clock-o"></i> ${formatDate(s.createdAt)}</span>
</div>
<div class="shared-link-actions">
<button class="icon-btn" data-action="copy" title="Link kopieren"><i class="fa fa-clipboard"></i></button>
<button class="icon-btn" data-action="open" title="Öffnen"><i class="fa fa-external-link"></i></button>
<button class="icon-btn danger-icon" data-action="delete" title="Link löschen"><i class="fa fa-trash"></i></button>
</div>
`;
row.querySelector('[data-action="copy"]').addEventListener('click', async () => {
const menuTrigger = card.querySelector('.card-menu-trigger');
const menuDropdown = card.querySelector('.card-menu-dropdown');
menuTrigger.addEventListener('click', (e) => {
e.stopPropagation();
closeAllCardMenus();
const rect = menuTrigger.getBoundingClientRect();
menuDropdown.hidden = false;
const dropRect = menuDropdown.getBoundingClientRect();
menuDropdown.style.top = `${rect.bottom + 4}px`;
menuDropdown.style.left = `${rect.right - dropRect.width}px`;
if (rect.bottom + 4 + dropRect.height > window.innerHeight) {
menuDropdown.style.top = `${rect.top - dropRect.height - 4}px`;
}
const finalRect = menuDropdown.getBoundingClientRect();
if (finalRect.left < 0) menuDropdown.style.left = '8px';
});
menuDropdown.querySelector('[data-action="copy"]').addEventListener('click', async (e) => {
e.stopPropagation();
menuDropdown.hidden = true;
await navigator.clipboard.writeText(shareUrl);
showToast('Link kopiert!');
});
row.querySelector('[data-action="open"]').addEventListener('click', () => {
menuDropdown.querySelector('[data-action="open"]').addEventListener('click', (e) => {
e.stopPropagation();
menuDropdown.hidden = true;
window.open(shareUrl, '_blank');
});
row.querySelector('[data-action="delete"]').addEventListener('click', async () => {
menuDropdown.querySelector('[data-action="delete"]').addEventListener('click', async (e) => {
e.stopPropagation();
menuDropdown.hidden = true;
await apiDeleteShare(s.shareToken);
row.remove();
if (sharedList.children.length === 0) sharedSection.hidden = true;
card.remove();
if (sharedGrid.children.length === 0) sharedSection.hidden = true;
showToast('Link gelöscht');
});
sharedList.appendChild(row);
sharedGrid.appendChild(card);
}
}
},