From 92b1c8a9bc4287a2f3d9d4428b8ae08727164e92 Mon Sep 17 00:00:00 2001 From: Meleki Date: Sun, 1 Mar 2026 11:18:12 +0100 Subject: [PATCH] =?UTF-8?q?Dashboard:=20Card-Men=C3=BC=20f=C3=BCr=20Sessio?= =?UTF-8?q?ns=20und=20Agents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Session-Cards: Menü mit 'Chat öffnen' und 'Bearbeiten' - Agent-Cards: Menü mit 'Bearbeiten' - Drei-Punkte-Trigger (ellipsis-v) erscheint bei Hover - Click-outside schließt offene Menüs - Card overflow auf visible geändert für Dropdown-Anzeige --- wwwroot/css/dashboard.css | 64 ++++++++++++++++++++++++++++++++- wwwroot/js/pages/dashboard.js | 66 +++++++++++++++++++++++++++++++++-- 2 files changed, 126 insertions(+), 4 deletions(-) diff --git a/wwwroot/css/dashboard.css b/wwwroot/css/dashboard.css index b59e307..a8ea5b7 100644 --- a/wwwroot/css/dashboard.css +++ b/wwwroot/css/dashboard.css @@ -21,11 +21,12 @@ } .card { + position: relative; background: var(--f3-bg); border: var(--border-width) solid var(--f3-border); display: flex; flex-direction: column; - overflow: hidden; + overflow: visible; border-radius: var(--border-radius); } @@ -42,6 +43,7 @@ aspect-ratio: 1; background: var(--f2-bg); overflow: hidden; + border-radius: var(--border-radius) var(--border-radius) 0 0; } .card-image img { @@ -99,6 +101,66 @@ padding: var(--button-padding); } +/* Card Menu */ + +.card-menu { + position: absolute; + top: var(--badge-spacing); + right: var(--badge-spacing); + z-index: 10; +} + +.card-menu-trigger { + opacity: 0; + transition: opacity .15s; + padding: .15em .45em; + font-size: var(--font-size); + background: var(--f3-bg); + border: var(--border-width) solid var(--f3-border); + border-radius: var(--border-radius); +} + +.card:hover .card-menu-trigger { + opacity: var(--semi-transparent); +} + +.card-menu-trigger:hover { + opacity: 1 !important; +} + +.card-menu-dropdown { + position: absolute; + top: 100%; + right: 0; + margin-top: .3em; + background: var(--f3-bg); + border: var(--border-width) solid var(--f3-border); + border-radius: var(--border-radius); + min-width: 10em; + display: flex; + flex-direction: column; + overflow: hidden; + padding-block: calc(var(--badge-spacing) / 2) var(--badge-spacing); +} + +.card-menu-dropdown[hidden] { + display: none; +} + +.card-menu-item { + border: none; + border-radius: unset; + text-align: left; + padding: var(--menu-item-padding); + background: none; + white-space: nowrap; +} + +.card-menu-item:not(:disabled):hover { + background: var(--f2-bg); + border: none; +} + .card-meta { display: flex; flex-direction: column; diff --git a/wwwroot/js/pages/dashboard.js b/wwwroot/js/pages/dashboard.js index e4b8178..7f33012 100644 --- a/wwwroot/js/pages/dashboard.js +++ b/wwwroot/js/pages/dashboard.js @@ -2,6 +2,9 @@ registerPage('dashboard', { async init() { + // Globaler Click-Handler zum Schließen aller Card-Menüs + document.addEventListener('click', this._closeCardMenus = () => closeAllCardMenus()); + const agents = await apiGetAgents(); const agentMap = {}; for (const a of agents) agentMap[a.agentId] = a; @@ -33,8 +36,35 @@ registerPage('dashboard', { ${workspaceLabel ? ` ${esc(workspaceLabel)}` : ''} +
+ + +
`; - card.addEventListener('click', () => navigateTo('session', { id: s.sessionId })); + card.addEventListener('click', (e) => { + if (e.target.closest('.card-menu')) return; + navigateTo('session', { id: s.sessionId }); + }); + const menuTrigger = card.querySelector('.card-menu-trigger'); + const menuDropdown = card.querySelector('.card-menu-dropdown'); + menuTrigger.addEventListener('click', (e) => { + e.stopPropagation(); + closeAllCardMenus(); + menuDropdown.hidden = !menuDropdown.hidden; + }); + menuDropdown.querySelector('[data-action="chat"]').addEventListener('click', (e) => { + e.stopPropagation(); + menuDropdown.hidden = true; + navigateTo('chat', { id: s.sessionId }); + }); + menuDropdown.querySelector('[data-action="edit"]').addEventListener('click', (e) => { + e.stopPropagation(); + menuDropdown.hidden = true; + navigateTo('session', { id: s.sessionId }); + }); grid.appendChild(card); // Git-Status asynchron laden @@ -100,8 +130,29 @@ registerPage('dashboard', { ${a.description ? `
${esc(a.description)}
` : ''} ${a.persona ? `
${esc(a.persona)}
` : ''} +
+ + +
`; - card.addEventListener('click', () => navigateTo('agent', { id: a.agentId })); + card.addEventListener('click', (e) => { + if (e.target.closest('.card-menu')) return; + navigateTo('agent', { id: a.agentId }); + }); + const menuTrigger = card.querySelector('.card-menu-trigger'); + const menuDropdown = card.querySelector('.card-menu-dropdown'); + menuTrigger.addEventListener('click', (e) => { + e.stopPropagation(); + closeAllCardMenus(); + menuDropdown.hidden = !menuDropdown.hidden; + }); + menuDropdown.querySelector('[data-action="edit"]').addEventListener('click', (e) => { + e.stopPropagation(); + menuDropdown.hidden = true; + navigateTo('agent', { id: a.agentId }); + }); agentGrid.appendChild(card); } @@ -111,9 +162,18 @@ registerPage('dashboard', { placeholder.addEventListener('click', () => navigateTo('agent')); document.getElementById('newAgentCard').appendChild(placeholder); }, - destroy() {} + destroy() { + if (this._closeCardMenus) { + document.removeEventListener('click', this._closeCardMenus); + this._closeCardMenus = null; + } + } }); +function closeAllCardMenus() { + document.querySelectorAll('.card-menu-dropdown').forEach(d => d.hidden = true); +} + function esc(s) { const d = document.createElement('div'); d.textContent = s;