Dashboard: Card-Menü für Sessions und Agents
- 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
This commit is contained in:
1 parent
5037c7d24e
commit
92b1c8a9bc
2 files changed
+126
-4
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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 ? `<span class="card-meta-item card-workspace" title="${esc(workspaceLabel)}"><i class="fa fa-folder"></i> ${esc(workspaceLabel)}</span>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
<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="chat">Chat öffnen</button>
|
||||
<button class="card-menu-item" data-action="edit">Bearbeiten</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
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 ? `<div class="card-desc">${esc(a.description)}</div>` : ''}
|
||||
${a.persona ? `<div class="card-meta"><span class="card-meta-item card-persona"><i class="fa fa-user-secret"></i> ${esc(a.persona)}</span></div>` : ''}
|
||||
</div>
|
||||
<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="edit">Bearbeiten</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
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;
|
||||
|
||||
Reference in new issue
Block a user