Files
gott/wwwroot/js/pages/session-page.js
T

206 lines
6.9 KiB
JavaScript

// ── Session Edit Page ──
let _sessionImageData = null;
let _sessionPasteHandler = null;
function _createCommandRow(container, name = '', command = '') {
const item = document.createElement('div');
item.className = 'custom-command-item';
item.innerHTML = `
<div class="custom-command-fields">
<input type="text" class="cmd-name" placeholder="Name (z.B. Deploy)" value="${_escAttr(name)}">
<input type="text" class="cmd-command" placeholder="Befehl (z.B. ./deploy.sh)" value="${_escAttr(command)}">
</div>
<button type="button" class="remove-cmd-btn icon-btn"><i class="fa fa-times"></i></button>
`;
item.querySelector('.remove-cmd-btn').addEventListener('click', () => item.remove());
container.appendChild(item);
}
function _escAttr(str) {
return str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function _getCommandsFromUI(container) {
const items = container.querySelectorAll('.custom-command-item');
const commands = [];
for (const item of items) {
const name = item.querySelector('.cmd-name').value.trim();
const command = item.querySelector('.cmd-command').value.trim();
if (name || command) commands.push({ name, command });
}
return commands.length > 0 ? commands : null;
}
registerPage('session', {
async init(params) {
const sessionId = params.id;
const isNew = !sessionId;
let session = null;
if (!isNew) {
session = await apiGetSession(sessionId);
if (!session) return navigateTo('dashboard');
}
const titleEl = document.getElementById('sessionPageTitle');
const nameEl = document.getElementById('sessionName');
const descEl = document.getElementById('sessionDescription');
const contextEl = document.getElementById('sessionContext');
const workspaceEl = document.getElementById('sessionWorkspace');
const agentSelect = document.getElementById('agentSelect');
const imagePreview = document.getElementById('sessionImagePreview');
const imageInput = document.getElementById('sessionImageInput');
const imageBtn = document.getElementById('sessionImageBtn');
const imageClearBtn = document.getElementById('sessionImageClearBtn');
const saveBtn = document.getElementById('sessionSaveBtn');
const cancelBtn = document.getElementById('sessionCancelBtn');
const deleteBtn = document.getElementById('sessionDeleteBtn');
const openChatBtn = document.getElementById('openChatBtn');
const commandsList = document.getElementById('customCommandsList');
const addCommandBtn = document.getElementById('addCommandBtn');
_sessionImageData = null;
if (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;
openChatBtn.disabled = false;
if (session.image) {
imagePreview.innerHTML = `<img src="${session.image}" alt="">`;
}
// Custom Commands laden
if (session.customCommands) {
try {
const cmds = typeof session.customCommands === 'string'
? JSON.parse(session.customCommands)
: session.customCommands;
for (const cmd of cmds) {
_createCommandRow(commandsList, cmd.name || '', cmd.command || '');
}
} catch (e) { /* ignore parse errors */ }
}
} else {
titleEl.textContent = 'Neue Session';
deleteBtn.hidden = true;
openChatBtn.disabled = true;
}
// Befehl hinzufügen
addCommandBtn.addEventListener('click', () => _createCommandRow(commandsList));
// Agents laden
const agents = await apiGetAgents();
agentSelect.innerHTML = '<option value="">-- Kein Agent --</option>';
for (const a of agents) {
const opt = document.createElement('option');
opt.value = a.agentId;
opt.textContent = `${a.name} (${a.model})`;
agentSelect.appendChild(opt);
}
if (session && session.agentId) agentSelect.value = session.agentId;
// Bild Upload
imageBtn.addEventListener('click', () => imageInput.click());
imageInput.addEventListener('change', () => {
const file = imageInput.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = () => {
_sessionImageData = reader.result;
imagePreview.innerHTML = `<img src="${reader.result}" alt="">`;
};
reader.readAsDataURL(file);
});
imageClearBtn.addEventListener('click', () => {
_sessionImageData = null;
imagePreview.innerHTML = '?';
imageInput.value = '';
});
// Bild Paste (Ctrl+V)
document.addEventListener('paste', _sessionPasteHandler = (e) => {
const items = e.clipboardData?.items;
if (!items) return;
for (const item of items) {
if (item.type.startsWith('image/')) {
e.preventDefault();
const file = item.getAsFile();
if (!file) return;
const reader = new FileReader();
reader.onload = () => {
_sessionImageData = reader.result;
imagePreview.innerHTML = `<img src="${reader.result}" alt="">`;
};
reader.readAsDataURL(file);
return;
}
}
});
// Workspace Browse
const workspaceBrowse = document.getElementById('sessionWorkspaceBrowse');
if (workspaceBrowse) {
workspaceBrowse.addEventListener('click', () => {
openFolderBrowser({
startPath: workspaceEl.value.trim() || '/',
onSelect(path) {
workspaceEl.value = path;
}
});
});
}
// Speichern
saveBtn.addEventListener('click', async () => {
const commands = _getCommandsFromUI(commandsList);
const data = {
name: nameEl.value.trim() || 'Unbenannt',
description: descEl.value.trim(),
image: _sessionImageData,
agentId: agentSelect.value || null,
context: contextEl.value || null,
workspace: workspaceEl.value.trim() || null,
customCommands: commands
};
if (isNew) {
await apiCreateSession(data);
} else {
await apiUpdateSession(sessionId, data);
}
navigateTo('dashboard');
});
// Abbrechen
cancelBtn.addEventListener('click', () => navigateTo('dashboard'));
// Löschen
deleteBtn.addEventListener('click', async () => {
if (!confirm('Session wirklich löschen?')) return;
await apiDeleteSession(sessionId);
navigateTo('dashboard');
});
// Chat öffnen
openChatBtn.addEventListener('click', () => {
navigateTo('chat', { id: sessionId });
});
},
destroy() {
if (_sessionPasteHandler) {
document.removeEventListener('paste', _sessionPasteHandler);
_sessionPasteHandler = null;
}
_sessionImageData = null;
}
});