Die monolithische ui.js (1534 Zeilen) zusammen mit chat.js (612) und history.js (626) in fokussierte Module aufgeteilt: Neue Dateien aus ui.js: - ui-helpers.js (126) - DOM-Utilities, $, esc, truncate, scrollDown, Toast - markdown.js (143) - renderMarkdown, wrapKreaGalleries, LaTeX/Code-Schutz - cards.js (90) - buildSessionCard, buildAgentCard - msg-actions.js (208) - Delete, Mark, Share, Reply-Button, Timestamp - tool-ui.js (332) - Tool-Boxes, Diffs, Todo-Liste, Visibility - modals.js (190) - System-Prompt, Command-Output, Krea-Image Modals - stream-ui.js (124) - Stream-Bubble, Review-Streaming - bubbles.js (312) - User/Assistant/Error/Warning/Choice/Review Bubbles Neue Dateien aus chat.js: - reply.js (54) - Reply/Quote-Handling mit pendingReply State - files.js (110) - File-Upload, Workspace-Refs mit pendingFiles/Refs State Neue Datei aus history.js: - archive.js (173) - Archiv-Loading mit loadedArchiveCount State Verbleibend: - chat.js (448) - Stream-Events, sendMessage, handleChoiceClick, Plan-Mode - history.js (464) - History laden, Polling, Message-Rendering Kein Code verändert, nur verschoben. Alle 94 Funktionen verifiziert. Globale Variablen in die Module verschoben, wo sie primär genutzt werden.
91 lines
5.5 KiB
JavaScript
91 lines
5.5 KiB
JavaScript
// ── Session Card Helper ──
|
|
// Erzeugt ein .card-Element für eine Session (wiederverwendbar für Dashboard + Picker).
|
|
|
|
function buildSessionCard(session, agent) {
|
|
const card = document.createElement('div');
|
|
card.className = 'card';
|
|
|
|
const transformParts = [];
|
|
if (session.avatarScale && session.avatarScale !== 1) transformParts.push(`scale(${session.avatarScale})`);
|
|
if (session.avatarOffsetX || session.avatarOffsetY) transformParts.push(`translate(${session.avatarOffsetX || 0}%, ${session.avatarOffsetY || 0}%)`);
|
|
const transformStyle = transformParts.length ? ` style="transform: ${transformParts.join(' ')}"` : '';
|
|
const imageHtml = session.image ? `<img src="${session.image}" alt=""${transformStyle}>` : '';
|
|
|
|
// Badges
|
|
const badges = [];
|
|
if (agent) badges.push(`<span class="badge">${esc(agent.name)}</span>`);
|
|
if (session.reviewAgentId) badges.push(`<span class="badge badge-feature" title="Review-Agent"><i class="fa fa-check-circle-o"></i></span>`);
|
|
if (session.finalizerAgentId) badges.push(`<span class="badge badge-feature" title="Finalizer-Agent"><i class="fa fa-flag-checkered"></i></span>`);
|
|
if (session.context) badges.push(`<span class="badge badge-feature" title="${esc(session.context)}"><i class="fa fa-file-text-o"></i></span>`);
|
|
if (session.telegramConfigured) badges.push(`<span class="badge ${session.telegramLinked ? 'badge-feature' : 'badge-off'}" title="Telegram ${session.telegramLinked ? 'verbunden' : 'konfiguriert'}"><i class="fa fa-paper-plane"></i></span>`);
|
|
|
|
// Meta
|
|
const metaParts = [];
|
|
if (session.messageCount) metaParts.push(`<span class="card-meta-item"><i class="fa fa-comment"></i> ${esc(session.messageCount + ' Nachrichten')}</span>`);
|
|
if (session.archiveMessageCount) metaParts.push(`<span class="card-meta-item"><i class="fa fa-archive"></i> ${esc(session.archiveMessageCount + ' Nachrichten archiviert')}</span>`);
|
|
if (session.workspace) metaParts.push(`<span class="card-meta-item card-workspace" title="${esc(session.workspace)}"><i class="fa fa-folder"></i> ${esc(session.workspace)}</span>`);
|
|
|
|
card.innerHTML = `
|
|
<div class="card-image">${imageHtml}</div>
|
|
<div class="card-body">
|
|
<div class="card-title-row">
|
|
<span class="card-title">${esc(session.name || 'Unbenannt')}</span>
|
|
${badges.join('')}
|
|
</div>
|
|
${metaParts.length ? `<div class="card-meta">${metaParts.join('')}</div>` : ''}
|
|
</div>
|
|
`;
|
|
|
|
return card;
|
|
}
|
|
|
|
|
|
// ── Agent Card Helper ──
|
|
// Erzeugt ein .card-Element für einen Agent (wiederverwendbar für Dashboard + Picker).
|
|
|
|
function buildAgentCard(agent, skills) {
|
|
const card = document.createElement('div');
|
|
card.className = 'card';
|
|
|
|
const agentTransformParts = [];
|
|
if (agent.avatarScale && agent.avatarScale !== 1) agentTransformParts.push(`scale(${agent.avatarScale})`);
|
|
if (agent.avatarOffsetX || agent.avatarOffsetY) agentTransformParts.push(`translate(${agent.avatarOffsetX || 0}%, ${agent.avatarOffsetY || 0}%)`);
|
|
const agentTransformStyle = agentTransformParts.length ? ` style="transform: ${agentTransformParts.join(' ')}"` : '';
|
|
const imageHtml = agent.avatar ? `<img src="${agent.avatar}" alt=""${agentTransformStyle}>` : '';
|
|
|
|
// Badges
|
|
const badges = [];
|
|
if (agent.toolChoice === 'any') badges.push('<span class="badge badge-forced-feature" title="Tool-Nutzung erzwingen"><i class="fa fa-wrench"></i> Erzwungen</span>');
|
|
if (agent.allowUserChoice) badges.push('<span class="badge badge-feature" title="Rückfragen per Auswahl erlaubt"><i class="fa fa-question-circle"></i> Rückfragen</span>');
|
|
if (agent.autoCommit === 'mention') badges.push('<span class="badge badge-feature" title="Git-Commits nur auf Anweisung"><i class="fa fa-code-fork"></i> Anmerken</span>');
|
|
if (agent.autoCommit === 'enforce') badges.push('<span class="badge badge-forced-feature" title="Git-Commits nach jeder Änderung erzwungen"><i class="fa fa-code-fork"></i> Erzwungen</span>');
|
|
if (agent.autoCommit === 'forbid') badges.push('<span class="badge badge-forced-feature" title="Git-Commits strikt verboten"><i class="fa fa-code-fork"></i> Verboten</span>');
|
|
if (agent.useSoul) badges.push('<span class="badge badge-feature" title="Hat eine Seele (SOUL.md)"><i class="fa fa-heart"></i> Seele</span>');
|
|
if (agent.useIdentity) badges.push('<span class="badge badge-feature" title="Hat eine Identität (IDENTITY.md)"><i class="fa fa-id-badge"></i> Ich</span>');
|
|
if (agent.useUserInfo) badges.push('<span class="badge badge-feature" title="Kennt sein Gegenüber (Benutzer-Persona)"><i class="fa fa-user"></i> Du</span>');
|
|
if (agent.useMemory) badges.push('<span class="badge badge-feature" title="Zugriff auf Erinnerungen (Memory-Tools)"><i class="fa fa-database"></i> Erinnerungen</span>');
|
|
if (agent.webSearchVersion) {
|
|
const wsYear = agent.webSearchVersion.includes('2025') ? 'Version 2025' : 'v2026';
|
|
badges.push(`<span class="badge badge-feature" title="Web-Suche - ${wsYear}"><i class="fa fa-search"></i> Web-Suche</span>`);
|
|
}
|
|
|
|
if (skills) {
|
|
for (const skill of skills) {
|
|
badges.push(`<span class="badge badge-skill" title="${esc(skill.description || skill.slug)}"><i class="fa fa-puzzle-piece"></i> ${esc(skill.name)}</span>`);
|
|
}
|
|
}
|
|
|
|
card.innerHTML = `
|
|
<div class="card-image">${imageHtml}</div>
|
|
<div class="card-body">
|
|
<div class="card-title-row">
|
|
<span class="card-title">${esc(agent.name)}</span>
|
|
<span class="badge">${prettyModelName(agent.model)}</span>
|
|
</div>
|
|
${badges.length ? `<div class="card-badges">${badges.join('')}</div>` : ''}
|
|
</div>
|
|
`;
|
|
|
|
return card;
|
|
}
|