feat (ui): compacte IDE-sidebar tree view voor Files tabblad
- Vervang kaart-stijl folder-rijen door compacte, platte rijen (2px padding, geen border) - Verwijder badge-tellers (📁 N, 📄 N) uit folder-rijen - Voeg .btn.tiny toe voor kleine actieknoppen (+/✕) in boom - Alle mappen standaard ingeklapt; localStorage behoudt uitgeklapte staat - file-entry hover highlight; verwijder bottom-border per rij Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,9 +21,10 @@ function filesSetEditorTheme(themeName) {
|
||||
|
||||
window.filesSetEditorTheme = filesSetEditorTheme;
|
||||
|
||||
function _isFolderCollapsed(folderKey) {
|
||||
return localStorage.getItem('files_folder_collapsed:' + folderKey) !== '0';
|
||||
// default collapsed = true
|
||||
function _isFolderCollapsed(folderKey, level) {
|
||||
const stored = localStorage.getItem('files_folder_collapsed:' + folderKey);
|
||||
if (stored !== null) return stored !== '0';
|
||||
return true; // standaard alles ingeklapt
|
||||
}
|
||||
|
||||
function _setFolderCollapsed(folderKey, v) {
|
||||
@@ -246,37 +247,26 @@ async function filesRefresh() {
|
||||
|
||||
function renderNode(node, level) {
|
||||
const folderKey = node.apiPath;
|
||||
const collapsed = _isFolderCollapsed(folderKey);
|
||||
const collapsed = _isFolderCollapsed(folderKey, level);
|
||||
const label = node.uiPath || 'root';
|
||||
const indent = Math.max(0, level) * 14;
|
||||
|
||||
const folder = folderByPath.get(folderKey);
|
||||
const files = (folder && folder.files) ? folder.files : [];
|
||||
|
||||
// subfolders (NU AL beschikbaar voor de badges)
|
||||
const childNames = Array.from(node.children.keys()).sort((a,b) => a.localeCompare(b));
|
||||
|
||||
// files (NU AL beschikbaar voor de badges)
|
||||
const sortedFiles = (files || []).slice().sort((a,b) => a.localeCompare(b));
|
||||
|
||||
const out = [];
|
||||
out.push(`
|
||||
<div class="mono file-folder-row" data-folder="${esc(folderKey)}" style="margin:${level === 0 ? '8px' : '6px'} 0 6px 0; padding-left:${indent}px; font-weight:600;">
|
||||
<span class="file-folder-left">
|
||||
<span class="folder-toggle">${collapsed ? '▶' : '▼'}</span>
|
||||
<span>📂 ${esc(label)}</span>
|
||||
</span>
|
||||
<span class="file-folder-meta" onclick="event.stopPropagation();">
|
||||
<span class="file-badge" title="Subfolders in deze map">📁 ${childNames.length}</span>
|
||||
<span class="file-badge" title="Bestanden in deze map">📄 ${sortedFiles.length}</span>
|
||||
|
||||
<span class="flex file-folder-actions">
|
||||
<button class="btn small ok" title="Nieuw bestand in ${esc(label)}" onclick="filesNewFileInFolder(decodeURIComponent('${encodeURIComponent(node.uiPath)}'))">+</button>
|
||||
<button class="btn small bad" title="Verwijder map (alleen als leeg)" onclick="filesDeleteFolder(decodeURIComponent('${encodeURIComponent(node.uiPath)}'))">🗑️</button>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`);
|
||||
out.push(`<div class="mono file-folder-row" data-folder="${esc(folderKey)}" style="padding-left:${indent}px;">
|
||||
<span class="file-folder-left">
|
||||
<span class="folder-toggle">${collapsed ? '▶' : '▼'}</span>
|
||||
<span>📂 ${esc(label)}</span>
|
||||
</span>
|
||||
<span class="file-folder-actions" onclick="event.stopPropagation();">
|
||||
<button class="btn tiny ok" title="Nieuw bestand in ${esc(label)}" onclick="filesNewFileInFolder(decodeURIComponent('${encodeURIComponent(node.uiPath)}'))">+</button>
|
||||
<button class="btn tiny bad" title="Verwijder map (alleen als leeg)" onclick="filesDeleteFolder(decodeURIComponent('${encodeURIComponent(node.uiPath)}'))">✕</button>
|
||||
</span>
|
||||
</div>`);
|
||||
|
||||
out.push(`<div class="file-folder-files" data-folder-files="${esc(folderKey)}" style="${collapsed ? 'display:none;' : ''}">`);
|
||||
|
||||
@@ -287,16 +277,14 @@ async function filesRefresh() {
|
||||
for (const f of sortedFiles) {
|
||||
const fullUi = node.uiPath ? `${node.uiPath}/${f}` : f;
|
||||
const fileKey = encodeURIComponent(fullUi);
|
||||
out.push(`
|
||||
<div class="file-entry" data-file="${fileKey}" style="padding-left:${indent + 18}px;">
|
||||
<span class="mono file-entry-name" onclick="filesOpen(decodeURIComponent('${fileKey}'))">📄 ${esc(f)}</span>
|
||||
<span class="file-entry-state"></span>
|
||||
</div>
|
||||
`);
|
||||
out.push(`<div class="file-entry" data-file="${fileKey}" style="padding-left:${indent + 16}px;">
|
||||
<span class="mono file-entry-name" onclick="filesOpen(decodeURIComponent('${fileKey}'))">📄 ${esc(f)}</span>
|
||||
<span class="file-entry-state"></span>
|
||||
</div>`);
|
||||
}
|
||||
|
||||
if (!childNames.length && !sortedFiles.length) {
|
||||
out.push(`<div class="muted" style="padding-left:${indent + 18}px;">(leeg)</div>`);
|
||||
out.push(`<div class="muted" style="padding-left:${indent + 16}px; font-size:0.85em;">(leeg)</div>`);
|
||||
}
|
||||
|
||||
out.push(`</div>`);
|
||||
@@ -311,30 +299,25 @@ async function filesRefresh() {
|
||||
const rootFolder = folderByPath.get(FILES_ROOT);
|
||||
if (rootFolder && (rootFolder.files || []).length) {
|
||||
const folderKey = FILES_ROOT;
|
||||
const collapsed = _isFolderCollapsed(folderKey);
|
||||
parts.unshift(`
|
||||
<div class="mono file-folder-row" data-folder="${esc(folderKey)}" style="margin:8px 0 6px 0; font-weight:600;">
|
||||
<span class="file-folder-left">
|
||||
<span class="folder-toggle">${collapsed ? '▶' : '▼'}</span>
|
||||
<span>📂 root</span>
|
||||
</span>
|
||||
<span class="flex" onclick="event.stopPropagation();">
|
||||
<button class="btn small ok" title="Nieuw bestand in root" onclick="filesNewFileInFolder('')">+</button>
|
||||
</span>
|
||||
</div>
|
||||
<div class="file-folder-files" data-folder-files="${esc(folderKey)}" style="${collapsed ? 'display:none;' : ''}">
|
||||
${(rootFolder.files || []).slice().sort((a,b)=>a.localeCompare(b)).map(f => {
|
||||
const fullUi = f;
|
||||
const fileKey = encodeURIComponent(fullUi);
|
||||
return `
|
||||
<div class="file-entry" data-file="${fileKey}" style="padding-left:18px;">
|
||||
<span class="mono file-entry-name" style="cursor:pointer" onclick="filesOpen(decodeURIComponent('${fileKey}'))">📄 ${esc(f)}</span>
|
||||
<span class="file-entry-state"></span>
|
||||
</div>
|
||||
`;
|
||||
}).join('')}
|
||||
</div>
|
||||
`);
|
||||
const collapsed = _isFolderCollapsed(folderKey, 0);
|
||||
parts.unshift(`<div class="mono file-folder-row" data-folder="${esc(folderKey)}">
|
||||
<span class="file-folder-left">
|
||||
<span class="folder-toggle">${collapsed ? '▶' : '▼'}</span>
|
||||
<span>📂 root</span>
|
||||
</span>
|
||||
<span class="file-folder-actions" onclick="event.stopPropagation();">
|
||||
<button class="btn tiny ok" title="Nieuw bestand in root" onclick="filesNewFileInFolder('')">+</button>
|
||||
</span>
|
||||
</div>
|
||||
<div class="file-folder-files" data-folder-files="${esc(folderKey)}" style="${collapsed ? 'display:none;' : ''}">
|
||||
${(rootFolder.files || []).slice().sort((a,b)=>a.localeCompare(b)).map(f => {
|
||||
const fileKey = encodeURIComponent(f);
|
||||
return `<div class="file-entry" data-file="${fileKey}" style="padding-left:16px;">
|
||||
<span class="mono file-entry-name" onclick="filesOpen(decodeURIComponent('${fileKey}'))">📄 ${esc(f)}</span>
|
||||
<span class="file-entry-state"></span>
|
||||
</div>`;
|
||||
}).join('')}
|
||||
</div>`);
|
||||
}
|
||||
|
||||
treeEl.innerHTML = parts.join('');
|
||||
|
||||
Reference in New Issue
Block a user