Folder-Browser für Workspace-Auswahl, Layout/Style Anpassungen

This commit is contained in:
Meleki committed 2026-02-27 09:43:58 +01:00
1 parent f4ad949db4
commit aa2d9f1200
6 files changed
+179 -23

No files matched your search

+108
View File
@@ -258,6 +258,114 @@ function feDoSelect() {
closeFileExplorer();
}
// ── Folder Browser Mode ──
// Nutzt /api/workspace/browse mit absolutem Pfad, zum Ordner-Auswählen.
function openFolderBrowser(opts = {}) {
if (_feState) closeFileExplorer();
_feState = {
mode: 'folder',
onSelect: opts.onSelect || null,
currentAbsPath: opts.startPath || '/',
history: []
};
const overlay = document.createElement('div');
overlay.id = 'feOverlay';
overlay.className = 'fe-overlay';
overlay.addEventListener('click', (e) => { if (e.target === overlay) closeFileExplorer(); });
const modal = document.createElement('div');
modal.className = 'fe-modal';
modal.innerHTML = `
<div class="fe-header">
<div class="fe-nav">
<button class="fe-btn" id="feBack" title="Zurück" disabled>←</button>
<span class="fe-path" id="fePath">/</span>
</div>
<button class="fe-btn" id="feClose">✕</button>
</div>
<div class="fe-body">
<div class="fe-sidebar fe-sidebar-full" id="feSidebar">
<div class="fe-loading">Laden...</div>
</div>
</div>
<div class="fe-footer" id="feFooter">
<span class="fe-info" id="feInfo"></span>
<button class="fe-btn fe-select-btn" id="feSelectBtn">Diesen Ordner wählen</button>
</div>
`;
overlay.appendChild(modal);
document.body.appendChild(overlay);
document.getElementById('feBack').addEventListener('click', fbGoBack);
document.getElementById('feClose').addEventListener('click', closeFileExplorer);
document.getElementById('feSelectBtn').addEventListener('click', () => {
if (_feState && _feState.onSelect) _feState.onSelect(_feState.currentAbsPath);
closeFileExplorer();
});
_feState._keyHandler = (e) => { if (e.key === 'Escape') closeFileExplorer(); };
document.addEventListener('keydown', _feState._keyHandler);
fbLoadDir(opts.startPath || '/');
}
async function fbLoadDir(absPath) {
if (!_feState) return;
const pathEl = document.getElementById('fePath');
const sidebar = document.getElementById('feSidebar');
const info = document.getElementById('feInfo');
pathEl.textContent = absPath;
info.textContent = absPath;
sidebar.innerHTML = '<div class="fe-loading">Laden...</div>';
try {
const resp = await fetch(`/api/workspace/browse?path=${encodeURIComponent(absPath)}`);
if (!resp.ok) {
const err = await resp.json().catch(() => ({}));
sidebar.innerHTML = `<div class="fe-error">${err.error || 'Fehler'}</div>`;
return;
}
const data = await resp.json();
_feState.currentAbsPath = data.current;
pathEl.textContent = data.current;
info.textContent = data.current;
sidebar.innerHTML = '';
for (const entry of data.entries) {
const item = document.createElement('div');
item.className = 'fe-item fe-dir';
item.textContent = '📁 ' + entry.name;
item.addEventListener('click', () => {
_feState.history.push(_feState.currentAbsPath);
fbLoadDir(entry.path);
});
sidebar.appendChild(item);
}
if (data.entries.length === 0) {
sidebar.innerHTML = '<div class="fe-empty">Leer</div>';
}
document.getElementById('feBack').disabled = _feState.history.length === 0;
} catch (e) {
sidebar.innerHTML = '<div class="fe-error">Netzwerk-Fehler</div>';
}
}
function fbGoBack() {
if (!_feState || _feState.history.length === 0) return;
const prev = _feState.history.pop();
fbLoadDir(prev);
}
// ── Helpers ──
function getFileIcon(ext) {
+13
View File
@@ -79,6 +79,19 @@ registerPage('session', {
imageInput.value = '';
});
// 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 data = {