Folder-Browser für Workspace-Auswahl, Layout/Style Anpassungen
This commit is contained in:
1 parent
f4ad949db4
commit
aa2d9f1200
6 files changed
+179
-23
No files matched your search
@@ -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) {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
Reference in new issue
Block a user