Custom Commands ins Header-Dropdown-Menü verschoben

- customCmdBar entfernt, Commands als header-menu-items ins Dropdown eingefügt
- Sektions-Labels: System, Agent, Session mit Separatoren
- Header-Menü-Init nach oben verschoben (vor Command-Aufbau)
- CSS: alte cmd-bar Styles entfernt, neue separator/label/cmd Styles
This commit is contained in:
Meleki committed 2026-02-28 22:02:18 +01:00
1 parent 38eaed12dd
commit 41d99ec840
3 files changed
+112 -131

No files matched your search

+15 -29
View File
@@ -13,35 +13,6 @@
border-radius: var(--border-radius) var(--border-radius) 0 0; border-radius: var(--border-radius) var(--border-radius) 0 0;
} }
/* Custom Command Buttons */
.custom-cmd-bar {
display: flex;
gap: var(--badge-spacing);
margin-left: var(--badge-spacing);
flex-wrap: wrap;
align-items: center;
}
.custom-cmd-bar:empty {
display: none;
}
.cmd-bar-label {
font-size: var(--font-size);
opacity: var(--semi-transparent);
white-space: nowrap;
}
.custom-cmd-btn:hover {
background: var(--f3-bg);
border-color: var(--f3-border);
}
.custom-cmd-btn.running {
opacity: var(--semi-transparent);
}
/* Header Menu */ /* Header Menu */
.header-menu { .header-menu {
@@ -82,6 +53,21 @@
border: none; border: none;
} }
.header-menu-separator {
border-top: var(--border-width) solid var(--f2-border);
}
.header-menu-label {
padding: var(--badge-spacing) .75em;
font-size: var(--font-size);
opacity: var(--semi-transparent);
white-space: nowrap;
}
.header-menu-cmd.running {
opacity: var(--semi-transparent);
}
.meta-bar { .meta-bar {
padding: var(--box-padding); padding: var(--box-padding);
background: var(--chat-bg); background: var(--chat-bg);
-1
View File
@@ -148,7 +148,6 @@
<header> <header>
<button class="back-btn icon-btn" id="chatBackBtn"><i class="fa fa-arrow-left"></i></button> <button class="back-btn icon-btn" id="chatBackBtn"><i class="fa fa-arrow-left"></i></button>
<h1 id="sessionTitle">-</h1> <h1 id="sessionTitle">-</h1>
<div class="custom-cmd-bar" id="customCmdBar"></div>
<div class="header-menu"> <div class="header-menu">
<button class="header-menu-trigger icon-btn" id="chatMenuBtn"><i class="fa fa-ellipsis-v"></i></button> <button class="header-menu-trigger icon-btn" id="chatMenuBtn"><i class="fa fa-ellipsis-v"></i></button>
<div class="header-menu-dropdown" id="chatMenuDropdown" hidden> <div class="header-menu-dropdown" id="chatMenuDropdown" hidden>
+97 -101
View File
@@ -57,10 +57,57 @@ registerPage('chat', {
titleEl.textContent = session.name || 'Unbenannt'; titleEl.textContent = session.name || 'Unbenannt';
} }
// Custom Command Buttons (Agent + Session) // Header-Menü (3-Dot)
const cmdBar = document.getElementById('customCmdBar'); const chatMenuBtn = document.getElementById('chatMenuBtn');
if (cmdBar) { const chatMenuDropdown = document.getElementById('chatMenuDropdown');
cmdBar.innerHTML = ''; if (chatMenuBtn && chatMenuDropdown) {
chatMenuBtn.addEventListener('click', (e) => {
e.stopPropagation();
chatMenuDropdown.hidden = !chatMenuDropdown.hidden;
});
document.addEventListener('click', this._closeMenu = () => {
chatMenuDropdown.hidden = true;
});
}
// System-Prompt anzeigen
const systemPromptBtn = document.getElementById('systemPromptBtn');
if (systemPromptBtn) systemPromptBtn.addEventListener('click', () => {
if (chatMenuDropdown) chatMenuDropdown.hidden = true;
showSystemPromptModal(sessionId);
});
// Archivieren
const archiveBtn = document.getElementById('archiveBtn');
if (archiveBtn) archiveBtn.addEventListener('click', () => {
if (chatMenuDropdown) chatMenuDropdown.hidden = true;
clearChat();
});
// Datenbank sichern
const backupDbBtn = document.getElementById('backupDbBtn');
if (backupDbBtn) backupDbBtn.addEventListener('click', async () => {
if (chatMenuDropdown) chatMenuDropdown.hidden = true;
backupDbBtn.disabled = true;
try {
await apiBackupDb();
setMetaHtml('<i class="fa fa-check-circle"></i> Backup erstellt und heruntergeladen');
} catch (e) {
console.error('Backup fehlgeschlagen:', e);
setMetaHtml('<i class="fa fa-times-circle"></i> Backup fehlgeschlagen');
} finally {
backupDbBtn.disabled = false;
}
});
// Custom Command Buttons ins Header-Menü einfügen
if (chatMenuDropdown) {
// "System"-Label ganz oben einfügen
const systemLabel = document.createElement('div');
systemLabel.className = 'header-menu-label';
systemLabel.textContent = 'System';
chatMenuDropdown.prepend(systemLabel);
let agentCmds = []; let agentCmds = [];
if (session.agentId) { if (session.agentId) {
try { try {
@@ -73,63 +120,55 @@ registerPage('chat', {
let sessionCmds = []; let sessionCmds = [];
try { sessionCmds = JSON.parse(session.customCommands || '[]') || []; } catch(e) {} try { sessionCmds = JSON.parse(session.customCommands || '[]') || []; } catch(e) {}
const allCmds = agentCmds.concat(sessionCmds); const addCmdSection = (cmds, label) => {
const hasAgentCmds = agentCmds.length > 0; const validCmds = cmds.filter(c => c.name && c.command);
const hasSessionCmds = sessionCmds.length > 0; if (validCmds.length === 0) return;
const hasBoth = hasAgentCmds && hasSessionCmds; const sep = document.createElement('div');
sep.className = 'header-menu-separator';
if (hasBoth) { chatMenuDropdown.appendChild(sep);
const sep1 = document.createElement('span'); const lbl = document.createElement('div');
sep1.className = 'cmd-bar-label'; lbl.className = 'header-menu-label';
sep1.textContent = 'Agent:'; lbl.textContent = label;
cmdBar.appendChild(sep1); chatMenuDropdown.appendChild(lbl);
} validCmds.forEach(cmd => {
if (!cmd.name || !cmd.command) return;
let sessionSepAdded = false; const type = cmd.type || 'background';
let cmdIndex = 0; const btn = document.createElement('button');
allCmds.forEach((cmd, idx) => { btn.className = 'header-menu-item header-menu-cmd';
if (hasBoth && !sessionSepAdded && idx === agentCmds.length) { btn.textContent = cmd.name;
const sep2 = document.createElement('span'); btn.title = type === 'message' ? cmd.command : `[${type}] ${cmd.command}`;
sep2.className = 'cmd-bar-label'; btn.addEventListener('click', async () => {
sep2.textContent = 'Session:'; chatMenuDropdown.hidden = true;
cmdBar.appendChild(sep2); if (type === 'message') {
sessionSepAdded = true; const inputEl = document.getElementById('input');
} if (inputEl) {
if (!cmd.name || !cmd.command) return; inputEl.value = cmd.command;
const type = cmd.type || 'background'; inputEl.dispatchEvent(new Event('input'));
const btn = document.createElement('button'); }
btn.className = 'custom-cmd-btn'; sendMessage();
if (type === 'message') btn.classList.add('cmd-type-message'); return;
btn.textContent = cmd.name;
btn.title = type === 'message' ? cmd.command : `[${type}] ${cmd.command}`;
btn.addEventListener('click', async () => {
if (type === 'message') {
// Nachricht in den Chat senden
const inputEl = document.getElementById('input');
if (inputEl) {
inputEl.value = cmd.command;
inputEl.dispatchEvent(new Event('input'));
} }
sendMessage(); btn.disabled = true;
return; btn.classList.add('running');
} try {
btn.disabled = true; if (type === 'foreground') {
btn.classList.add('running'); const result = await apiExecCommand(sessionId, cmd.command, 'foreground');
try { showCommandOutputModal(cmd.name, cmd.command, result);
if (type === 'foreground') { } else {
const result = await apiExecCommand(sessionId, cmd.command, 'foreground'); await apiExecCommand(sessionId, cmd.command, 'background');
showCommandOutputModal(cmd.name, cmd.command, result); }
} else { } catch(e) {
await apiExecCommand(sessionId, cmd.command, 'background'); console.error('Exec failed:', e);
} }
} catch(e) { btn.disabled = false;
console.error('Exec failed:', e); btn.classList.remove('running');
} });
btn.disabled = false; chatMenuDropdown.appendChild(btn);
btn.classList.remove('running');
}); });
cmdBar.appendChild(btn); };
});
addCmdSection(agentCmds, 'Agent');
addCmdSection(sessionCmds, 'Session');
} }
// Zurück zur Session-Edit-Seite // Zurück zur Session-Edit-Seite
@@ -207,49 +246,6 @@ registerPage('chat', {
}); });
} }
// Header-Menü (3-Dot)
const chatMenuBtn = document.getElementById('chatMenuBtn');
const chatMenuDropdown = document.getElementById('chatMenuDropdown');
if (chatMenuBtn && chatMenuDropdown) {
chatMenuBtn.addEventListener('click', (e) => {
e.stopPropagation();
chatMenuDropdown.hidden = !chatMenuDropdown.hidden;
});
document.addEventListener('click', this._closeMenu = () => {
chatMenuDropdown.hidden = true;
});
}
// System-Prompt anzeigen
const systemPromptBtn = document.getElementById('systemPromptBtn');
if (systemPromptBtn) systemPromptBtn.addEventListener('click', () => {
if (chatMenuDropdown) chatMenuDropdown.hidden = true;
showSystemPromptModal(sessionId);
});
// Archivieren
const archiveBtn = document.getElementById('archiveBtn');
if (archiveBtn) archiveBtn.addEventListener('click', () => {
if (chatMenuDropdown) chatMenuDropdown.hidden = true;
clearChat();
});
// Datenbank sichern
const backupDbBtn = document.getElementById('backupDbBtn');
if (backupDbBtn) backupDbBtn.addEventListener('click', async () => {
if (chatMenuDropdown) chatMenuDropdown.hidden = true;
backupDbBtn.disabled = true;
try {
await apiBackupDb();
setMetaHtml('<i class="fa fa-check-circle"></i> Backup erstellt und heruntergeladen');
} catch (e) {
console.error('Backup fehlgeschlagen:', e);
setMetaHtml('<i class="fa fa-times-circle"></i> Backup fehlgeschlagen');
} finally {
backupDbBtn.disabled = false;
}
});
// State zurücksetzen und History laden // State zurücksetzen und History laden
messages.length = 0; messages.length = 0;
lastKnownMessageId = 0; lastKnownMessageId = 0;