diff --git a/TODO.md b/TODO.md index 99cbda3..646309d 100644 --- a/TODO.md +++ b/TODO.md @@ -34,7 +34,7 @@ - [x] Chat: Es werden momentan alle Tool-Calls angezeigt - die Anzeige soll individuell in den Einstellungen gemacht werden können. Auswahl aus drei Stufen: "Alle anzeigen" / "Nur Modifikationen" (file änderungen, memory änderungen, etc.) / "Verstecken" - [x] Browser: "Zurück"-Taste soll auf den vorherigen location.hash wechseln - [x] File Explorer: CodeMirror lässt sich horizontal nicht scroll -- [ ] Chat: Datum und Uhrzeit bei den Nachrichten anzeigen (Format: dd.MM.yyyy HH:mm:ss) +- [x] Chat: Datum und Uhrzeit bei den Nachrichten anzeigen (Format: dd.MM.yyyy HH:mm:ss) - [x] Dashboard: Menu-Dropdown bei Cards sind abgeschnitten wenn die Card-Höhe nicht ausreicht (logisch, weil das Menu-Dropdown ein Child von der Card ist) - [ ] Auto-scrolling deaktivieren, wenn man weiterhoch gescrollt hat, und er wieder fortsetzen wenn man ganz nach unten gescrollt hat - [x] Anstelle von `[Bild: ...]`-Platzhalter direkt das gesendete Bild anzeigen diff --git a/wwwroot/css/base.css b/wwwroot/css/base.css index b08f9cc..8441814 100644 --- a/wwwroot/css/base.css +++ b/wwwroot/css/base.css @@ -118,3 +118,7 @@ a { a:hover { text-decoration: underline; } + +ul { + margin-left: 1.5em; +} diff --git a/wwwroot/css/form.css b/wwwroot/css/form.css index edb942d..00709ed 100644 --- a/wwwroot/css/form.css +++ b/wwwroot/css/form.css @@ -407,3 +407,26 @@ label.skill-item { gap: var(--badge-spacing); cursor: pointer; } + +/* ── EasyMDE in Formularen ── */ +/* Nutzt fe-mde-wrap Styles aus file-explorer.css für Dark-Theme, + überschreibt aber die Fullscreen-Layout-Regeln für den Formular-Kontext. */ + +.form .fe-mde-wrap { + display: block; + flex: none; + height: auto; + overflow: visible; +} + +.form .fe-mde-wrap .CodeMirror { + height: auto !important; + border: var(--border-width) solid var(--f2-border) !important; + border-top: none !important; + border-radius: 0 0 var(--border-radius) var(--border-radius) !important; + padding: var(--box-padding) !important; +} + +.form .fe-mde-wrap .editor-toolbar { + border-radius: var(--border-radius) var(--border-radius) 0 0 !important; +} diff --git a/wwwroot/js/pages/profile-page.js b/wwwroot/js/pages/profile-page.js index 4491bbf..6d9bab1 100644 --- a/wwwroot/js/pages/profile-page.js +++ b/wwwroot/js/pages/profile-page.js @@ -1,5 +1,7 @@ // ── Profile Page ── +var _profileMde = null; + registerPage('profile', { async init() { var profile = await apiGetProfile(); @@ -11,6 +13,21 @@ registerPage('profile', { var saveBtn = document.getElementById('profileSaveBtn'); var messageDiv = document.getElementById('profileMessage'); + // EasyMDE für Persona + _profileMde = new EasyMDE({ + element: personaInput, + initialValue: profile.persona || '', + toolbar: ['bold', 'italic', 'heading', '|', 'unordered-list', 'ordered-list', '|', 'link', 'code', '|', 'preview'], + status: false, + spellChecker: false, + autoDownloadFontAwesome: false, + minHeight: '150px', + placeholder: 'Beschreibe dich selbst – Name, Rolle, Präferenzen, Kommunikationsstil...', + previewClass: ['editor-preview', 'markdown'] + }); + _profileMde.codemirror.setOption('theme', 'default'); + _profileMde.codemirror.getWrapperElement().closest('.EasyMDEContainer').classList.add('fe-mde-wrap'); + var currentPwInput = document.getElementById('profileCurrentPassword'); var newPwInput = document.getElementById('profileNewPassword'); var confirmPwInput = document.getElementById('profileConfirmPassword'); @@ -22,7 +39,6 @@ registerPage('profile', { // Felder befüllen usernameInput.value = profile.username || ''; displayNameInput.value = profile.displayName || ''; - personaInput.value = profile.persona || ''; // Profil speichern saveBtn.addEventListener('click', async function() { @@ -33,7 +49,7 @@ registerPage('profile', { try { var updated = await apiUpdateProfile({ displayName: displayNameInput.value.trim(), - persona: personaInput.value.trim() + persona: _profileMde.value().trim() }); // currentUser aktualisieren @@ -108,5 +124,10 @@ registerPage('profile', { navigateTo('login'); }); }, - destroy() {} + destroy() { + if (_profileMde) { + _profileMde.toTextArea(); + _profileMde = null; + } + } }); diff --git a/wwwroot/js/pages/session-page.js b/wwwroot/js/pages/session-page.js index 116421f..f7ae717 100644 --- a/wwwroot/js/pages/session-page.js +++ b/wwwroot/js/pages/session-page.js @@ -2,6 +2,7 @@ let _sessionImageData = null; let _sessionPasteHandler = null; +let _sessionContextMde = null; registerPage('session', { async init(params) { @@ -36,7 +37,6 @@ registerPage('session', { titleEl.textContent = session.name || 'Unbenannt'; nameEl.value = session.name || ''; descEl.value = session.description || ''; - contextEl.value = session.context || ''; workspaceEl.value = session.workspace || ''; _sessionImageData = session.image || null; deleteBtn.hidden = false; @@ -52,6 +52,21 @@ registerPage('session', { deleteBtn.hidden = true; } + // EasyMDE für Kontext + _sessionContextMde = new EasyMDE({ + element: contextEl, + initialValue: (session && session.context) || '', + toolbar: ['bold', 'italic', 'heading', '|', 'unordered-list', 'ordered-list', '|', 'link', 'code', '|', 'preview'], + status: false, + spellChecker: false, + autoDownloadFontAwesome: false, + minHeight: '120px', + placeholder: 'Zusätzlicher Kontext für den System-Prompt (optional)', + previewClass: ['editor-preview', 'markdown'] + }); + _sessionContextMde.codemirror.setOption('theme', 'default'); + _sessionContextMde.codemirror.getWrapperElement().closest('.EasyMDEContainer').classList.add('fe-mde-wrap'); + // Befehl hinzufügen addCommandBtn.addEventListener('click', () => createCommandRow(commandsList)); @@ -131,7 +146,7 @@ registerPage('session', { description: descEl.value.trim(), image: _sessionImageData, agentId: agentSelect.value || null, - context: contextEl.value || null, + context: _sessionContextMde.value().trim() || null, workspace: workspaceEl.value.trim() || null, customCommands: commands }; @@ -166,6 +181,10 @@ registerPage('session', { }); }, destroy() { + if (_sessionContextMde) { + _sessionContextMde.toTextArea(); + _sessionContextMde = null; + } if (_sessionPasteHandler) { document.removeEventListener('paste', _sessionPasteHandler); _sessionPasteHandler = null;