feat(files-dashboard) mappen in en uitklapbaar
This commit is contained in:
+55
-3
@@ -381,6 +381,24 @@
|
|||||||
.sidebar .navLabel { display: none; }
|
.sidebar .navLabel { display: none; }
|
||||||
.sidebar .tab { justify-content: center; }
|
.sidebar .tab { justify-content: center; }
|
||||||
}
|
}
|
||||||
|
.file-folder-row{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:space-between;
|
||||||
|
gap:10px;
|
||||||
|
cursor:pointer;
|
||||||
|
user-select:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-folder-left{
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
gap:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-folder-files{
|
||||||
|
margin-left: 18px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@@ -861,6 +879,15 @@
|
|||||||
localStorage.setItem('pod_group_collapsed:' + pod, v ? '1' : '0');
|
localStorage.setItem('pod_group_collapsed:' + pod, v ? '1' : '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _isFolderCollapsed(folderKey) {
|
||||||
|
return localStorage.getItem('files_folder_collapsed:' + folderKey) !== '0';
|
||||||
|
// default collapsed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function _setFolderCollapsed(folderKey, v) {
|
||||||
|
localStorage.setItem('files_folder_collapsed:' + folderKey, v ? '1' : '0');
|
||||||
|
}
|
||||||
|
|
||||||
function renderActionsDropdown(menuId, actionFn, targetEsc) {
|
function renderActionsDropdown(menuId, actionFn, targetEsc) {
|
||||||
// actionFn is string: "containerAction" of "podAction"
|
// actionFn is string: "containerAction" of "podAction"
|
||||||
// targetEsc is al esc(...) dus veilig in onclick
|
// targetEsc is al esc(...) dus veilig in onclick
|
||||||
@@ -1382,11 +1409,16 @@
|
|||||||
const apiFolderPath = (folder.path || '').replace(/^\/+/, '');
|
const apiFolderPath = (folder.path || '').replace(/^\/+/, '');
|
||||||
const uiFolderPath = filesToUiPath(apiFolderPath); // zonder systemd/
|
const uiFolderPath = filesToUiPath(apiFolderPath); // zonder systemd/
|
||||||
const folderLabel = uiFolderPath || 'root';
|
const folderLabel = uiFolderPath || 'root';
|
||||||
|
const folderKey = apiFolderPath; // unieke key (met systemd/..)
|
||||||
|
const collapsed = _isFolderCollapsed(folderKey);
|
||||||
|
|
||||||
parts.push(`
|
parts.push(`
|
||||||
<div class="mono" style="margin:8px 0 6px 0; font-weight:600; display:flex; align-items:center; justify-content:space-between; gap:10px;">
|
<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>📂 ${esc(folderLabel)}</span>
|
<span>📂 ${esc(folderLabel)}</span>
|
||||||
<span class="flex">
|
</span>
|
||||||
|
<span class="flex" onclick="event.stopPropagation();">
|
||||||
<button class="btn small ok" title="Nieuw bestand in ${esc(folderLabel)}" onclick="filesNewFileInFolder('${esc(uiFolderPath)}')">+</button>
|
<button class="btn small ok" title="Nieuw bestand in ${esc(folderLabel)}" onclick="filesNewFileInFolder('${esc(uiFolderPath)}')">+</button>
|
||||||
<button class="btn small bad" title="Verwijder map (alleen als leeg)" onclick="filesDeleteFolder('${esc(uiFolderPath)}')">🗑️</button>
|
<button class="btn small bad" title="Verwijder map (alleen als leeg)" onclick="filesDeleteFolder('${esc(uiFolderPath)}')">🗑️</button>
|
||||||
</span>
|
</span>
|
||||||
@@ -1399,17 +1431,37 @@
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parts.push(`<div class="file-folder-files" data-folder-files="${esc(folderKey)}" style="${collapsed ? 'display:none;' : ''}">`);
|
||||||
|
|
||||||
for (const f of files) {
|
for (const f of files) {
|
||||||
const fullUi = uiFolderPath ? `${uiFolderPath}/${f}` : f;
|
const fullUi = uiFolderPath ? `${uiFolderPath}/${f}` : f;
|
||||||
parts.push(`
|
parts.push(`
|
||||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-left:10px;padding:4px 0;border-bottom:1px dashed rgba(36,52,95,.35)">
|
<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;padding:4px 0;border-bottom:1px dashed rgba(36,52,95,.35)">
|
||||||
<span class="mono" style="cursor:pointer" onclick="filesOpen('${esc(fullUi)}')">📄 ${esc(f)}</span>
|
<span class="mono" style="cursor:pointer" onclick="filesOpen('${esc(fullUi)}')">📄 ${esc(f)}</span>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parts.push(`</div>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
treeEl.innerHTML = parts.join('');
|
treeEl.innerHTML = parts.join('');
|
||||||
|
treeEl.onclick = (ev) => {
|
||||||
|
const row = ev.target.closest('.file-folder-row');
|
||||||
|
if (!row) return;
|
||||||
|
|
||||||
|
const folderKey = row.getAttribute('data-folder');
|
||||||
|
const isNowCollapsed = !_isFolderCollapsed(folderKey);
|
||||||
|
_setFolderCollapsed(folderKey, isNowCollapsed);
|
||||||
|
|
||||||
|
// pijltje updaten
|
||||||
|
const arrow = row.querySelector('.folder-toggle');
|
||||||
|
if (arrow) arrow.textContent = isNowCollapsed ? '▶' : '▼';
|
||||||
|
|
||||||
|
// files block tonen/verbergen
|
||||||
|
const filesBlock = treeEl.querySelector(`[data-folder-files="${CSS.escape(folderKey)}"]`);
|
||||||
|
if (filesBlock) filesBlock.style.display = isNowCollapsed ? 'none' : '';
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function filesOpen(uiPath) {
|
async function filesOpen(uiPath) {
|
||||||
|
|||||||
Reference in New Issue
Block a user